Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Enumerations | Functions | Variables
func_callerid.c File Reference

Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting) More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/callerid.h"
Include dependency graph for func_callerid.c:

Go to the source code of this file.

Data Structures

struct  __subtype_ast_party_func_args
 
struct  __subtype_ast_party_members
 
struct  ast_party_func_args
 
struct  ast_party_members
 

Enumerations

enum  CONNECTED_LINE_OPT_ARGS { CONNECTED_LINE_OPT_DUMMY , CONNECTED_LINE_OPT_ARG_ARRAY_SIZE }
 
enum  CONNECTED_LINE_OPT_FLAGS { CONNECTED_LINE_OPT_INHIBIT = (1 << 0) }
 
enum  ID_FIELD_STATUS { ID_FIELD_VALID , ID_FIELD_INVALID , ID_FIELD_UNKNOWN }
 
enum  REDIRECTING_OPT_ARGS { REDIRECTING_OPT_DUMMY , REDIRECTING_OPT_ARG_ARRAY_SIZE }
 
enum  REDIRECTING_OPT_FLAGS { REDIRECTING_OPT_INHIBIT = (1 << 0) }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int callerid_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int callerid_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
static int connectedline_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int connectedline_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
static int load_module (void)
 
static enum ID_FIELD_STATUS party_id_read (char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
 
static enum ID_FIELD_STATUS party_id_write (struct ast_party_id *id, int argc, char *argv[], const char *value)
 
static enum ID_FIELD_STATUS party_name_read (char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
 
static enum ID_FIELD_STATUS party_name_write (struct ast_party_name *name, int argc, char *argv[], const char *value)
 
static enum ID_FIELD_STATUS party_number_read (char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
 
static enum ID_FIELD_STATUS party_number_write (struct ast_party_number *number, int argc, char *argv[], const char *value)
 
static enum ID_FIELD_STATUS party_subaddress_read (char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
 
static enum ID_FIELD_STATUS party_subaddress_write (struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
 
static int redirecting_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int redirecting_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function callerid_function
 
static struct ast_custom_function connectedline_function
 
static const struct ast_app_option connectedline_opts [128] = { [ 'i' ] = { .flag = CONNECTED_LINE_OPT_INHIBIT }, }
 
static struct ast_custom_function redirecting_function
 
static const struct ast_app_option redirecting_opts [128] = { [ 'i' ] = { .flag = REDIRECTING_OPT_INHIBIT }, }
 

Detailed Description

Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)

See Also:

Definition in file func_callerid.c.

Enumeration Type Documentation

◆ CONNECTED_LINE_OPT_ARGS

Enumerator
CONNECTED_LINE_OPT_DUMMY 

Delete this if CONNECTED_LINE ever gets an option with parameters.

CONNECTED_LINE_OPT_ARG_ARRAY_SIZE 
Note
This entry MUST be the last one in the enum

Definition at line 480 of file func_callerid.c.

480 {
481 CONNECTED_LINE_OPT_DUMMY, /*!< Delete this if CONNECTED_LINE ever gets an option with parameters. */
482
483 /*! \note This entry _MUST_ be the last one in the enum */
485};
@ CONNECTED_LINE_OPT_ARG_ARRAY_SIZE
@ CONNECTED_LINE_OPT_DUMMY

◆ CONNECTED_LINE_OPT_FLAGS

Enumerator
CONNECTED_LINE_OPT_INHIBIT 

Definition at line 477 of file func_callerid.c.

477 {
479};
@ CONNECTED_LINE_OPT_INHIBIT

◆ ID_FIELD_STATUS

Enumerator
ID_FIELD_VALID 
ID_FIELD_INVALID 
ID_FIELD_UNKNOWN 

Definition at line 461 of file func_callerid.c.

461 {
465};
@ ID_FIELD_INVALID
@ ID_FIELD_VALID
@ ID_FIELD_UNKNOWN

◆ REDIRECTING_OPT_ARGS

Enumerator
REDIRECTING_OPT_DUMMY 

Delete this if REDIRECTING ever gets an option with parameters.

REDIRECTING_OPT_ARG_ARRAY_SIZE 
Note
This entry MUST be the last one in the enum

Definition at line 494 of file func_callerid.c.

494 {
495 REDIRECTING_OPT_DUMMY, /*!< Delete this if REDIRECTING ever gets an option with parameters. */
496
497 /*! \note This entry _MUST_ be the last one in the enum */
499};
@ REDIRECTING_OPT_ARG_ARRAY_SIZE
@ REDIRECTING_OPT_DUMMY

◆ REDIRECTING_OPT_FLAGS

Enumerator
REDIRECTING_OPT_INHIBIT 

Definition at line 491 of file func_callerid.c.

491 {
492 REDIRECTING_OPT_INHIBIT = (1 << 0),
493};
@ REDIRECTING_OPT_INHIBIT

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1861 of file func_callerid.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1861 of file func_callerid.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1861 of file func_callerid.c.

◆ callerid_read()

static int callerid_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

< Member name

< Optional caller id to parse instead of from the channel.

Definition at line 956 of file func_callerid.c.

957{
958 char *parms;
959 struct ast_party_members member = { 0, };
961 AST_APP_ARG(member); /*!< Member name */
962 AST_APP_ARG(cid); /*!< Optional caller id to parse instead of from the channel. */
963 );
964
965 /* Ensure that the buffer is empty */
966 *buf = 0;
967
968 if (!chan) {
969 return -1;
970 }
971
972 parms = ast_strdupa(data);
974 if (args.argc == 0) {
975 /* Must have at least one argument. */
976 return -1;
977 }
978
980 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
981 /* Too few or too many subnames */
982 return -1;
983 }
984
985 if (args.argc == 2) {
986 char name[80];
987 char num[80];
988
989 ast_callerid_split(args.cid, name, sizeof(name), num, sizeof(num));
990
991 if (member.argc == 1 && !strcasecmp("all", member.subnames[0])) {
992 snprintf(buf, len, "\"%s\" <%s>", name, num);
993 } else if (member.argc == 1 && !strcasecmp("name", member.subnames[0])) {
995 } else if (member.argc == 1 && !strncasecmp("num", member.subnames[0], 3)) {
996 /* Accept num[ber] */
997 ast_copy_string(buf, num, len);
998 } else {
999 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1000 }
1001 } else {
1003 ast_channel_lock(chan);
1004
1005 if (member.argc == 1 && !strcasecmp("rdnis", member.subnames[0])) {
1006 if (ast_channel_redirecting(chan)->from.number.valid
1007 && ast_channel_redirecting(chan)->from.number.str) {
1008 ast_copy_string(buf, ast_channel_redirecting(chan)->from.number.str, len);
1009 }
1010 } else if (!strcasecmp("dnid", member.subnames[0])) {
1011 if (member.argc == 1) {
1012 /* Setup as if user had given dnid-num instead. */
1013 member.argc = 2;
1014 member.subnames[1] = "num";
1015 }
1016 if (!strncasecmp("num", member.subnames[1], 3)) {
1017 /*
1018 * Accept num[ber]
1019 * dnid-num...
1020 */
1021 if (member.argc == 2) {
1022 /* dnid-num */
1023 if (ast_channel_dialed(chan)->number.str) {
1025 }
1026 } else if (member.argc == 3 && !strcasecmp("plan", member.subnames[2])) {
1027 /* dnid-num-plan */
1028 snprintf(buf, len, "%d", ast_channel_dialed(chan)->number.plan);
1029 } else {
1030 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1031 }
1032 } else if (!strncasecmp("subaddr", member.subnames[1], 7)) {
1033 /*
1034 * Accept subaddr[ess]
1035 * dnid-subaddr...
1036 */
1037 status = party_subaddress_read(buf, len, member.argc - 2, member.subnames + 2,
1038 &ast_channel_dialed(chan)->subaddress);
1039 switch (status) {
1040 case ID_FIELD_VALID:
1041 case ID_FIELD_INVALID:
1042 break;
1043 default:
1044 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1045 break;
1046 }
1047 } else {
1048 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1049 }
1050 } else if (member.argc == 1 && !strcasecmp("ani2", member.subnames[0])) {
1051 /* ANI2 is always formatted as two digits:
1052 * https://nanpa.com/numbering/ani-ii-digits */
1053 snprintf(buf, len, "%02d", ast_channel_caller(chan)->ani2);
1054 } else if (!strcasecmp("ani", member.subnames[0])) {
1055 if (member.argc == 1) {
1056 /* Setup as if user had given ani-num instead. */
1057 member.argc = 2;
1058 member.subnames[1] = "num";
1059 }
1060 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1061 &ast_channel_caller(chan)->ani);
1062 switch (status) {
1063 case ID_FIELD_VALID:
1064 case ID_FIELD_INVALID:
1065 break;
1066 default:
1067 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1068 break;
1069 }
1070 } else if (!strcasecmp("priv", member.subnames[0])) {
1071 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1072 &ast_channel_caller(chan)->priv);
1073 switch (status) {
1074 case ID_FIELD_VALID:
1075 case ID_FIELD_INVALID:
1076 break;
1077 default:
1078 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1079 break;
1080 }
1081 } else {
1082 status = party_id_read(buf, len, member.argc, member.subnames, &ast_channel_caller(chan)->id);
1083 switch (status) {
1084 case ID_FIELD_VALID:
1085 case ID_FIELD_INVALID:
1086 break;
1087 default:
1088 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1089 break;
1090 }
1091 }
1092
1093 ast_channel_unlock(chan);
1094 }
1095
1096 return 0;
1097}
jack_status_t status
Definition: app_jack.c:149
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1292
#define ast_channel_lock(chan)
Definition: channel.h:2972
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static const char name[]
Definition: format_mp3.c:68
ID_FIELD_STATUS
static enum ID_FIELD_STATUS party_id_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_id *id)
static enum ID_FIELD_STATUS party_subaddress_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_subaddress *subaddress)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
#define LOG_ERROR
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Number structure.
Definition: app_followme.c:157
const char * args
#define ARRAY_LEN(a)
Definition: utils.h:666

References args, ARRAY_LEN, AST_APP_ARG, ast_callerid_split(), ast_channel_caller(), ast_channel_dialed(), ast_channel_lock, ast_channel_redirecting(), ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, buf, ID_FIELD_INVALID, ID_FIELD_VALID, len(), LOG_ERROR, name, party_id_read(), party_subaddress_read(), and status.

◆ callerid_write()

static int callerid_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 1111 of file func_callerid.c.

1112{
1113 struct ast_party_caller caller;
1114 struct ast_party_dialed dialed;
1116 char *val;
1117 char *parms;
1118 struct ast_party_func_args args = { 0, };
1119 struct ast_party_members member = { 0, };
1120
1121 if (!value || !chan) {
1122 return -1;
1123 }
1124
1125 parms = ast_strdupa(data);
1127 if (args.argc == 0) {
1128 /* Must have at least one argument. */
1129 return -1;
1130 }
1131
1132 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1133 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1134 /* Too few or too many subnames */
1135 return -1;
1136 }
1137
1139
1140 ast_channel_lock(chan);
1141 if (member.argc == 1 && !strcasecmp("rdnis", member.subnames[0])) {
1143 ast_free(ast_channel_redirecting(chan)->from.number.str);
1145 } else if (!strcasecmp("dnid", member.subnames[0])) {
1147 if (member.argc == 1) {
1148 /* Setup as if user had given dnid-num instead. */
1149 member.argc = 2;
1150 member.subnames[1] = "num";
1151 }
1152 if (!strncasecmp("num", member.subnames[1], 3)) {
1153 /*
1154 * Accept num[ber]
1155 * dnid-num...
1156 */
1157 if (member.argc == 2) {
1158 /* dnid-num */
1159 dialed.number.str = ast_strdup(value);
1160 ast_trim_blanks(dialed.number.str);
1162 } else if (member.argc == 3 && !strcasecmp("plan", member.subnames[2])) {
1163 /* dnid-num-plan */
1166
1167 if (('0' <= val[0]) && (val[0] <= '9')) {
1168 ast_channel_dialed(chan)->number.plan = atoi(val);
1169 } else {
1171 "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
1172 }
1173 } else {
1174 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1175 }
1176 } else if (!strncasecmp("subaddr", member.subnames[1], 7)) {
1177 /*
1178 * Accept subaddr[ess]
1179 * dnid-subaddr...
1180 */
1181 status = party_subaddress_write(&dialed.subaddress, member.argc - 2,
1182 member.subnames + 2, value);
1183 switch (status) {
1184 case ID_FIELD_VALID:
1186 break;
1187 case ID_FIELD_INVALID:
1188 break;
1189 default:
1190 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1191 break;
1192 }
1193 } else {
1194 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1195 }
1196 ast_party_dialed_free(&dialed);
1197 } else if (member.argc == 1 && !strcasecmp("ani2", member.subnames[0])) {
1200
1201 if (('0' <= val[0]) && (val[0] <= '9')) {
1202 ast_channel_caller(chan)->ani2 = atoi(val);
1203 } else {
1204 ast_log(LOG_ERROR, "Unknown callerid ani2 '%s', value unchanged\n", val);
1205 }
1206 } else if (!strcasecmp("ani", member.subnames[0])) {
1208 if (member.argc == 1) {
1209 /* Setup as if user had given ani-num instead. */
1210 member.argc = 2;
1211 member.subnames[1] = "num";
1212 }
1213 status = party_id_write(&caller.ani, member.argc - 1, member.subnames + 1, value);
1214 switch (status) {
1215 case ID_FIELD_VALID:
1217 break;
1218 case ID_FIELD_INVALID:
1219 break;
1220 default:
1221 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1222 break;
1223 }
1224 ast_party_caller_free(&caller);
1225 } else if (!strcasecmp("priv", member.subnames[0])) {
1227 status = party_id_write(&caller.priv, member.argc - 1, member.subnames + 1, value);
1228 switch (status) {
1229 case ID_FIELD_VALID:
1231 break;
1232 case ID_FIELD_INVALID:
1233 break;
1234 default:
1235 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1236 break;
1237 }
1238 ast_party_caller_free(&caller);
1239 } else {
1241 status = party_id_write(&caller.id, member.argc, member.subnames, value);
1242 switch (status) {
1243 case ID_FIELD_VALID:
1244 ast_channel_set_caller_event(chan, &caller, NULL);
1245 break;
1246 case ID_FIELD_INVALID:
1247 break;
1248 default:
1249 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
1250 break;
1251 }
1252 ast_party_caller_free(&caller);
1253 }
1254 ast_channel_unlock(chan);
1255
1256 return 0;
1257}
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
Initialize the given dialed structure using the given guide for a set update operation.
Definition: channel.c:1917
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
Definition: channel.c:7345
void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
Set the caller information based on another caller source.
Definition: channel.c:1974
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
Definition: channel.c:1966
void ast_party_dialed_free(struct ast_party_dialed *doomed)
Destroy the dialed party contents.
Definition: channel.c:1938
void ast_party_caller_free(struct ast_party_caller *doomed)
Destroy the caller party contents.
Definition: channel.c:1982
void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
Set the dialed information based on another dialed source.
Definition: channel.c:1925
static enum ID_FIELD_STATUS party_id_write(struct ast_party_id *id, int argc, char *argv[], const char *value)
static enum ID_FIELD_STATUS party_subaddress_write(struct ast_party_subaddress *subaddress, int argc, char *argv[], const char *value)
#define NULL
Definition: resample.c:96
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:186
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
Caller Party information.
Definition: channel.h:420
int ani2
Automatic Number Identification 2 (Info Digits)
Definition: channel.h:435
Dialed/Called Party information.
Definition: channel.h:380
struct ast_party_dialed::@210 number
Dialed/Called number.
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:390
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:344
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:299
char * str
Subscriber phone number (Malloced)
Definition: channel.h:293
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:529
Definition: ast_expr2.c:325
int value
Definition: syslog.c:37

References ast_party_caller::ani, ast_party_caller::ani2, args, ARRAY_LEN, ast_channel_caller(), ast_channel_dialed(), ast_channel_lock, ast_channel_redirecting(), ast_channel_set_caller_event(), ast_channel_unlock, ast_free, ast_log, AST_NONSTANDARD_APP_ARGS, ast_party_caller_free(), ast_party_caller_set(), ast_party_caller_set_init(), ast_party_dialed_free(), ast_party_dialed_set(), ast_party_dialed_set_init(), ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdup, ast_strdupa, ast_trim_blanks(), ast_party_redirecting::from, ast_party_caller::id, ID_FIELD_INVALID, ID_FIELD_VALID, LOG_ERROR, NULL, ast_party_id::number, ast_party_dialed::number, party_id_write(), party_subaddress_write(), ast_party_dialed::plan, ast_party_caller::priv, status, ast_party_number::str, ast_party_dialed::str, ast_party_dialed::subaddress, ast_party_number::valid, and value.

◆ connectedline_read()

static int connectedline_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1272 of file func_callerid.c.

1273{
1274 struct ast_party_members member = { 0, };
1275 char *read_what;
1277
1278 /* Ensure that the buffer is empty */
1279 *buf = 0;
1280
1281 if (!chan) {
1282 return -1;
1283 }
1284
1285 read_what = ast_strdupa(data);
1286 AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1287 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1288 /* Too few or too many subnames */
1289 return -1;
1290 }
1291
1292 ast_channel_lock(chan);
1293
1294 if (member.argc == 1 && !strcasecmp("source", member.subnames[0])) {
1296 } else if (!strcasecmp("priv", member.subnames[0])) {
1297 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1298 &ast_channel_connected(chan)->priv);
1299 switch (status) {
1300 case ID_FIELD_VALID:
1301 case ID_FIELD_INVALID:
1302 break;
1303 default:
1304 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1305 break;
1306 }
1307 } else {
1308 status = party_id_read(buf, len, member.argc, member.subnames, &ast_channel_connected(chan)->id);
1309 switch (status) {
1310 case ID_FIELD_VALID:
1311 case ID_FIELD_INVALID:
1312 break;
1313 default:
1314 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1315 break;
1316 }
1317 }
1318
1319 ast_channel_unlock(chan);
1320
1321 return 0;
1322}
const char * ast_connected_line_source_name(int data)
Convert connected line update source value to text code.
Definition: callerid.c:1505
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)

References ARRAY_LEN, ast_channel_connected(), ast_channel_lock, ast_channel_unlock, ast_connected_line_source_name(), ast_copy_string(), ast_log, AST_NONSTANDARD_APP_ARGS, ast_strdupa, buf, ID_FIELD_INVALID, ID_FIELD_VALID, len(), LOG_ERROR, party_id_read(), and status.

◆ connectedline_write()

static int connectedline_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 1336 of file func_callerid.c.

1337{
1339 char *val;
1340 char *parms;
1341 void (*set_it)(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update);
1342 struct ast_party_func_args args = { 0, };
1343 struct ast_party_members member = { 0, };
1344 struct ast_flags opts;
1345 char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
1347
1348 if (!value || !chan) {
1349 return -1;
1350 }
1351
1352 parms = ast_strdupa(data);
1354 if (args.argc == 0) {
1355 /* Must have at least one argument. */
1356 return -1;
1357 }
1358
1359 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1360 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1361 /* Too few or too many subnames */
1362 return -1;
1363 }
1364
1365 if (ast_app_parse_options(connectedline_opts, &opts, opt_args, args.opts)) {
1366 /* General invalid option syntax. */
1367 return -1;
1368 }
1369
1370 /* Determine if the update indication inhibit option is present */
1373 } else {
1375 }
1376
1377 ast_channel_lock(chan);
1379 ast_channel_unlock(chan);
1380
1382
1383 if (member.argc == 1 && !strcasecmp("source", member.subnames[0])) {
1384 int source;
1385
1388
1389 if (('0' <= val[0]) && (val[0] <= '9')) {
1390 source = atoi(val);
1391 } else {
1393 }
1394
1395 if (source < 0) {
1396 ast_log(LOG_ERROR, "Unknown connectedline source '%s', value unchanged\n", val);
1397 } else {
1398 connected.source = source;
1399 set_it(chan, &connected, NULL);
1400 }
1401 } else if (!strcasecmp("priv", member.subnames[0])) {
1402 status = party_id_write(&connected.priv, member.argc - 1, member.subnames + 1, value);
1403 switch (status) {
1404 case ID_FIELD_VALID:
1405 set_it(chan, &connected, NULL);
1406 break;
1407 case ID_FIELD_INVALID:
1408 break;
1409 default:
1410 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1411 break;
1412 }
1414 } else {
1415 status = party_id_write(&connected.id, member.argc, member.subnames, value);
1416 switch (status) {
1417 case ID_FIELD_VALID:
1418 set_it(chan, &connected, NULL);
1419 break;
1420 case ID_FIELD_INVALID:
1421 break;
1422 default:
1423 ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
1424 break;
1425 }
1427 }
1428
1429 return 0;
1430}
int ast_connected_line_source_parse(const char *data)
Convert connected line update source text code to value (used in config file parsing)
Definition: callerid.c:1479
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
Definition: channel.c:8313
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2039
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
Definition: channel.c:9098
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation.
Definition: channel.c:2012
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
char connected
Definition: eagi_proxy.c:82
static const struct ast_app_option connectedline_opts[128]
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Definition: utils.h:199
Connected Line/Party information.
Definition: channel.h:458
Indicate what information in ast_party_connected_line should be set.
Definition: channel.h:491
#define ast_test_flag(p, flag)
Definition: utils.h:63

References args, ARRAY_LEN, ast_app_parse_options(), ast_channel_connected(), ast_channel_lock, ast_channel_set_connected_line(), ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_source_parse(), ast_log, AST_NONSTANDARD_APP_ARGS, ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_test_flag, ast_trim_blanks(), connected, CONNECTED_LINE_OPT_ARG_ARRAY_SIZE, CONNECTED_LINE_OPT_INHIBIT, connectedline_opts, ID_FIELD_INVALID, ID_FIELD_VALID, LOG_ERROR, NULL, party_id_write(), status, update(), and value.

◆ load_module()

static int load_module ( void  )
static

Definition at line 1844 of file func_callerid.c.

1845{
1846 int res;
1847
1851
1852 if (res) {
1853 unload_module();
1855 }
1856
1858}
static struct ast_custom_function callerid_function
static struct ast_custom_function connectedline_function
static int unload_module(void)
static struct ast_custom_function redirecting_function
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559

References ast_custom_function_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, callerid_function, connectedline_function, redirecting_function, and unload_module().

◆ party_id_read()

static enum ID_FIELD_STATUS party_id_read ( char *  buf,
size_t  len,
int  argc,
char *  argv[],
const struct ast_party_id id 
)
static

Definition at line 635 of file func_callerid.c.

636{
638
639 if (argc == 0) {
640 /* Must have at least one subname. */
641 return ID_FIELD_UNKNOWN;
642 }
643
645
646 if (argc == 1 && !strcasecmp("all", argv[0])) {
647 snprintf(buf, len, "\"%s\" <%s>",
648 S_COR(id->name.valid, id->name.str, ""),
649 S_COR(id->number.valid, id->number.str, ""));
650 } else if (!strcasecmp("name", argv[0])) {
651 status = party_name_read(buf, len, argc - 1, argv + 1, &id->name);
652 } else if (!strncasecmp("num", argv[0], 3)) {
653 /* Accept num[ber] */
654 status = party_number_read(buf, len, argc - 1, argv + 1, &id->number);
655 } else if (!strncasecmp("subaddr", argv[0], 7)) {
656 /* Accept subaddr[ess] */
657 status = party_subaddress_read(buf, len, argc - 1, argv + 1, &id->subaddress);
658 } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
659 if (id->tag) {
660 ast_copy_string(buf, id->tag, len);
661 }
662 } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
663 /* ton is an alias for num-plan */
664 snprintf(buf, len, "%d", id->number.plan);
665 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
666 /*
667 * Accept pres[entation]
668 * This is the combined name/number presentation.
669 */
672 } else {
674 }
675
676 return status;
677}
enum queue_result id
Definition: app_queue.c:1808
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
Definition: callerid.c:1382
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1788
static enum ID_FIELD_STATUS party_name_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_name *name)
static enum ID_FIELD_STATUS party_number_read(char *buf, size_t len, int argc, char *argv[], const struct ast_party_number *number)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87

References ast_copy_string(), ast_named_caller_presentation(), ast_party_id_presentation(), buf, id, ID_FIELD_UNKNOWN, ID_FIELD_VALID, len(), party_name_read(), party_number_read(), party_subaddress_read(), S_COR, and status.

Referenced by callerid_read(), connectedline_read(), and redirecting_read().

◆ party_id_write()

static enum ID_FIELD_STATUS party_id_write ( struct ast_party_id id,
int  argc,
char *  argv[],
const char *  value 
)
static

Definition at line 870 of file func_callerid.c.

871{
872 char *val;
874
875 if (argc == 0) {
876 /* Must have at least one subname. */
877 return ID_FIELD_UNKNOWN;
878 }
879
881
882 if (argc == 1 && !strcasecmp("all", argv[0])) {
883 char name[256];
884 char num[256];
885
886 ast_callerid_split(value, name, sizeof(name), num, sizeof(num));
887 id->name.valid = 1;
888 id->name.str = ast_strdup(name);
889 if (!id->name.str) {
890 return ID_FIELD_INVALID;
891 }
892 id->number.valid = 1;
893 id->number.str = ast_strdup(num);
894 if (!id->number.str) {
895 return ID_FIELD_INVALID;
896 }
897 } else if (!strcasecmp("name", argv[0])) {
898 status = party_name_write(&id->name, argc - 1, argv + 1, value);
899 } else if (!strncasecmp("num", argv[0], 3)) {
900 /* Accept num[ber] */
901 status = party_number_write(&id->number, argc - 1, argv + 1, value);
902 } else if (!strncasecmp("subaddr", argv[0], 7)) {
903 /* Accept subaddr[ess] */
904 status = party_subaddress_write(&id->subaddress, argc - 1, argv + 1, value);
905 } else if (argc == 1 && !strcasecmp("tag", argv[0])) {
906 id->tag = ast_strdup(value);
907 ast_trim_blanks(id->tag);
908 } else if (argc == 1 && !strcasecmp("ton", argv[0])) {
909 /* ton is an alias for num-plan */
910 argv[0] = "plan";
911 status = party_number_write(&id->number, argc, argv, value);
912 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
913 int pres;
914
915 /*
916 * Accept pres[entation]
917 * This is the combined name/number presentation.
918 */
921
922 if (('0' <= val[0]) && (val[0] <= '9')) {
923 pres = atoi(val);
924 } else {
926 }
927
928 if (pres < 0) {
930 "Unknown combined presentation '%s', value unchanged\n", val);
932 } else {
933 id->name.presentation = pres;
934 id->number.presentation = pres;
935 }
936 } else {
938 }
939
940 return status;
941}
int ast_parse_caller_presentation(const char *data)
Convert caller ID text code to value (used in config file parsing)
Definition: callerid.c:1343
static enum ID_FIELD_STATUS party_name_write(struct ast_party_name *name, int argc, char *argv[], const char *value)
static enum ID_FIELD_STATUS party_number_write(struct ast_party_number *number, int argc, char *argv[], const char *value)

References ast_callerid_split(), ast_log, ast_parse_caller_presentation(), ast_strdup, ast_strdupa, ast_trim_blanks(), id, ID_FIELD_INVALID, ID_FIELD_UNKNOWN, ID_FIELD_VALID, LOG_ERROR, name, party_name_write(), party_number_write(), party_subaddress_write(), status, and value.

Referenced by callerid_write(), connectedline_write(), and redirecting_write().

◆ party_name_read()

static enum ID_FIELD_STATUS party_name_read ( char *  buf,
size_t  len,
int  argc,
char *  argv[],
const struct ast_party_name name 
)
static

Definition at line 519 of file func_callerid.c.

520{
522
524
525 if (argc == 0) {
526 /* We want the name string */
527 if (name->valid && name->str) {
528 ast_copy_string(buf, name->str, len);
529 }
530 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
531 snprintf(buf, len, "%d", name->valid);
532 } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
534 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
535 /* Accept pres[entation] */
537 } else {
539 }
540
541 return status;
542}
const char * ast_party_name_charset_str(int data)
Convert ast_party_name.char_set value to text code.
Definition: callerid.c:1560

References ast_copy_string(), ast_named_caller_presentation(), ast_party_name_charset_str(), buf, ID_FIELD_UNKNOWN, ID_FIELD_VALID, len(), name, and status.

Referenced by party_id_read().

◆ party_name_write()

static enum ID_FIELD_STATUS party_name_write ( struct ast_party_name name,
int  argc,
char *  argv[],
const char *  value 
)
static

Definition at line 693 of file func_callerid.c.

694{
695 char *val;
697
699
700 if (argc == 0) {
701 /* We are setting the name string */
702 name->valid = 1;
703 name->str = ast_strdup(value);
704 ast_trim_blanks(name->str);
705 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
706 name->valid = atoi(value) ? 1 : 0;
707 } else if (argc == 1 && !strcasecmp("charset", argv[0])) {
708 int char_set;
709
712
713 if (('0' <= val[0]) && (val[0] <= '9')) {
714 char_set = atoi(val);
715 } else {
717 }
718
719 if (char_set < 0) {
721 "Unknown name char-set '%s', value unchanged\n", val);
723 } else {
724 name->char_set = char_set;
725 }
726 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
727 int pres;
728
729 /* Accept pres[entation] */
732
733 if (('0' <= val[0]) && (val[0] <= '9')) {
734 pres = atoi(val);
735 } else {
737 }
738
739 if (pres < 0) {
741 "Unknown name presentation '%s', value unchanged\n", val);
743 } else {
744 name->presentation = pres;
745 }
746 } else {
748 }
749
750 return status;
751}
int ast_party_name_charset_parse(const char *data)
Convert ast_party_name.char_set text code to value (used in config file parsing)
Definition: callerid.c:1534

References ast_log, ast_parse_caller_presentation(), ast_party_name_charset_parse(), ast_strdup, ast_strdupa, ast_trim_blanks(), ID_FIELD_INVALID, ID_FIELD_UNKNOWN, ID_FIELD_VALID, LOG_ERROR, name, status, and value.

Referenced by party_id_write().

◆ party_number_read()

static enum ID_FIELD_STATUS party_number_read ( char *  buf,
size_t  len,
int  argc,
char *  argv[],
const struct ast_party_number number 
)
static

Definition at line 558 of file func_callerid.c.

559{
561
563
564 if (argc == 0) {
565 /* We want the number string */
566 if (number->valid && number->str) {
568 }
569 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
570 snprintf(buf, len, "%d", number->valid);
571 } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
572 snprintf(buf, len, "%d", number->plan);
573 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
574 /* Accept pres[entation] */
576 } else {
578 }
579
580 return status;
581}

References ast_copy_string(), ast_named_caller_presentation(), buf, ID_FIELD_UNKNOWN, ID_FIELD_VALID, len(), and status.

Referenced by party_id_read().

◆ party_number_write()

static enum ID_FIELD_STATUS party_number_write ( struct ast_party_number number,
int  argc,
char *  argv[],
const char *  value 
)
static

Definition at line 767 of file func_callerid.c.

768{
769 char *val;
771
773
774 if (argc == 0) {
775 /* We are setting the number string */
776 number->valid = 1;
777 number->str = ast_strdup(value);
779 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
780 number->valid = atoi(value) ? 1 : 0;
781 } else if (argc == 1 && !strcasecmp("plan", argv[0])) {
784
785 if (('0' <= val[0]) && (val[0] <= '9')) {
786 number->plan = atoi(val);
787 } else {
789 "Unknown type-of-number/numbering-plan '%s', value unchanged\n", val);
791 }
792 } else if (argc == 1 && !strncasecmp("pres", argv[0], 4)) {
793 int pres;
794
795 /* Accept pres[entation] */
798
799 if (('0' <= val[0]) && (val[0] <= '9')) {
800 pres = atoi(val);
801 } else {
803 }
804
805 if (pres < 0) {
807 "Unknown number presentation '%s', value unchanged\n", val);
809 } else {
810 number->presentation = pres;
811 }
812 } else {
814 }
815
816 return status;
817}

References ast_log, ast_parse_caller_presentation(), ast_strdup, ast_strdupa, ast_trim_blanks(), ID_FIELD_INVALID, ID_FIELD_UNKNOWN, ID_FIELD_VALID, LOG_ERROR, status, and value.

Referenced by party_id_write().

◆ party_subaddress_read()

static enum ID_FIELD_STATUS party_subaddress_read ( char *  buf,
size_t  len,
int  argc,
char *  argv[],
const struct ast_party_subaddress subaddress 
)
static

Definition at line 597 of file func_callerid.c.

598{
600
602
603 if (argc == 0) {
604 /* We want the subaddress string */
605 if (subaddress->str) {
606 ast_copy_string(buf, subaddress->str, len);
607 }
608 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
609 snprintf(buf, len, "%d", subaddress->valid);
610 } else if (argc == 1 && !strcasecmp("type", argv[0])) {
611 snprintf(buf, len, "%d", subaddress->type);
612 } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
613 snprintf(buf, len, "%d", subaddress->odd_even_indicator);
614 } else {
616 }
617
618 return status;
619}
unsigned char odd_even_indicator
TRUE if odd number of address signals.
Definition: channel.h:328
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:330
char * str
Malloced subaddress string.
Definition: channel.h:315
int type
Q.931 subaddress type.
Definition: channel.h:322

References ast_copy_string(), buf, ID_FIELD_UNKNOWN, ID_FIELD_VALID, len(), ast_party_subaddress::odd_even_indicator, status, ast_party_subaddress::str, ast_party_subaddress::type, and ast_party_subaddress::valid.

Referenced by callerid_read(), and party_id_read().

◆ party_subaddress_write()

static enum ID_FIELD_STATUS party_subaddress_write ( struct ast_party_subaddress subaddress,
int  argc,
char *  argv[],
const char *  value 
)
static

Definition at line 833 of file func_callerid.c.

834{
836
838
839 if (argc == 0) {
840 /* We are setting the subaddress string */
841 subaddress->str = ast_strdup(value);
842 ast_trim_blanks(subaddress->str);
843 } else if (argc == 1 && !strcasecmp("valid", argv[0])) {
844 subaddress->valid = atoi(value) ? 1 : 0;
845 } else if (argc == 1 && !strcasecmp("type", argv[0])) {
846 subaddress->type = atoi(value) ? 2 : 0;
847 } else if (argc == 1 && !strcasecmp("odd", argv[0])) {
848 subaddress->odd_even_indicator = atoi(value) ? 1 : 0;
849 } else {
851 }
852
853 return status;
854}

References ast_strdup, ast_trim_blanks(), ID_FIELD_UNKNOWN, ID_FIELD_VALID, ast_party_subaddress::odd_even_indicator, status, ast_party_subaddress::str, ast_party_subaddress::type, ast_party_subaddress::valid, and value.

Referenced by callerid_write(), and party_id_write().

◆ redirecting_read()

static int redirecting_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
)
static

Definition at line 1445 of file func_callerid.c.

1446{
1447 struct ast_party_members member = { 0, };
1448 char *read_what;
1449 const struct ast_party_redirecting *ast_redirecting;
1451
1452 /* Ensure that the buffer is empty */
1453 *buf = 0;
1454
1455 if (!chan) {
1456 return -1;
1457 }
1458
1459 read_what = ast_strdupa(data);
1460 AST_NONSTANDARD_APP_ARGS(member, read_what, '-');
1461 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1462 /* Too few or too many subnames */
1463 return -1;
1464 }
1465
1466 ast_channel_lock(chan);
1467
1468 ast_redirecting = ast_channel_redirecting(chan);
1469 if (!strcasecmp("orig", member.subnames[0])) {
1470 if (member.argc == 2 && !strcasecmp("reason", member.subnames[1])) {
1472 ast_redirecting_reason_name(&ast_redirecting->orig_reason), len);
1473 } else {
1474 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1475 &ast_redirecting->orig);
1476 switch (status) {
1477 case ID_FIELD_VALID:
1478 case ID_FIELD_INVALID:
1479 break;
1480 default:
1481 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1482 break;
1483 }
1484 }
1485 } else if (!strcasecmp("from", member.subnames[0])) {
1486 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1487 &ast_redirecting->from);
1488 switch (status) {
1489 case ID_FIELD_VALID:
1490 case ID_FIELD_INVALID:
1491 break;
1492 default:
1493 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1494 break;
1495 }
1496 } else if (!strcasecmp("to", member.subnames[0])) {
1497 status = party_id_read(buf, len, member.argc - 1, member.subnames + 1,
1498 &ast_redirecting->to);
1499 switch (status) {
1500 case ID_FIELD_VALID:
1501 case ID_FIELD_INVALID:
1502 break;
1503 default:
1504 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1505 break;
1506 }
1507 } else if (member.argc == 1 && !strncasecmp("pres", member.subnames[0], 4)) {
1508 /*
1509 * Accept pres[entation]
1510 * This is the combined from name/number presentation.
1511 */
1514 ast_party_id_presentation(&ast_redirecting->from)), len);
1515 } else if (member.argc == 1 && !strcasecmp("reason", member.subnames[0])) {
1517 } else if (member.argc == 1 && !strcasecmp("count", member.subnames[0])) {
1518 snprintf(buf, len, "%d", ast_redirecting->count);
1519 } else if (1 < member.argc && !strcasecmp("priv", member.subnames[0])) {
1520 if (!strcasecmp("orig", member.subnames[1])) {
1521 status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1522 &ast_redirecting->priv_orig);
1523 switch (status) {
1524 case ID_FIELD_VALID:
1525 case ID_FIELD_INVALID:
1526 break;
1527 default:
1528 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1529 break;
1530 }
1531 } else if (!strcasecmp("from", member.subnames[1])) {
1532 status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1533 &ast_redirecting->priv_from);
1534 switch (status) {
1535 case ID_FIELD_VALID:
1536 case ID_FIELD_INVALID:
1537 break;
1538 default:
1539 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1540 break;
1541 }
1542 } else if (!strcasecmp("to", member.subnames[1])) {
1543 status = party_id_read(buf, len, member.argc - 2, member.subnames + 2,
1544 &ast_redirecting->priv_to);
1545 switch (status) {
1546 case ID_FIELD_VALID:
1547 case ID_FIELD_INVALID:
1548 break;
1549 default:
1550 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1551 break;
1552 }
1553 } else {
1554 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1555 }
1556 } else {
1557 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1558 }
1559
1560 ast_channel_unlock(chan);
1561
1562 return 0;
1563}
const char * ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
Convert redirecting reason value to text code.
Definition: callerid.c:1449
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:524
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation.
Definition: channel.h:541
struct ast_party_redirecting_reason orig_reason
Reason for the redirection by the original party.
Definition: channel.h:547
struct ast_party_redirecting_reason reason
Reason for the redirection.
Definition: channel.h:544
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
Definition: channel.h:538
int count
Number of times the call was redirected.
Definition: channel.h:550
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:532
struct ast_party_id orig
Who originally redirected the call (Sent to the party the call is redirected toward)
Definition: channel.h:526
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
Definition: channel.h:535

References ARRAY_LEN, ast_channel_lock, ast_channel_redirecting(), ast_channel_unlock, ast_copy_string(), ast_log, ast_named_caller_presentation(), AST_NONSTANDARD_APP_ARGS, ast_party_id_presentation(), ast_redirecting_reason_name(), ast_strdupa, buf, ast_party_redirecting::count, ast_party_redirecting::from, ID_FIELD_INVALID, ID_FIELD_VALID, len(), LOG_ERROR, ast_party_redirecting::orig, ast_party_redirecting::orig_reason, party_id_read(), ast_party_redirecting::priv_from, ast_party_redirecting::priv_orig, ast_party_redirecting::priv_to, ast_party_redirecting::reason, status, and ast_party_redirecting::to.

◆ redirecting_write()

static int redirecting_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 1577 of file func_callerid.c.

1578{
1579 struct ast_party_redirecting redirecting;
1581 char *val;
1582 char *parms;
1583 void (*set_it)(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update);
1584 struct ast_party_func_args args = { 0, };
1585 struct ast_party_members member = { 0, };
1586 struct ast_flags opts;
1587 char *opt_args[REDIRECTING_OPT_ARG_ARRAY_SIZE];
1588
1589 if (!value || !chan) {
1590 return -1;
1591 }
1592
1593 parms = ast_strdupa(data);
1595 if (args.argc == 0) {
1596 /* Must have at least one argument. */
1597 return -1;
1598 }
1599
1600 AST_NONSTANDARD_APP_ARGS(member, args.member, '-');
1601 if (member.argc == 0 || ARRAY_LEN(member.subnames) <= member.argc) {
1602 /* Too few or too many subnames */
1603 return -1;
1604 }
1605
1606 if (ast_app_parse_options(redirecting_opts, &opts, opt_args, args.opts)) {
1607 /* General invalid option syntax. */
1608 return -1;
1609 }
1610
1611 /* Determine if the update indication inhibit option is present */
1614 } else {
1616 }
1617
1618 ast_channel_lock(chan);
1620 ast_channel_unlock(chan);
1621
1623
1624 if (!strcasecmp("orig", member.subnames[0])) {
1625 if (member.argc == 2 && !strcasecmp("reason", member.subnames[1])) {
1626 int reason;
1627
1630
1631 if (('0' <= val[0]) && (val[0] <= '9')) {
1632 reason = atoi(val);
1633 } else {
1635 }
1636
1637 if (reason < 0) {
1638 /* The argument passed into the function does not correspond to a pre-defined
1639 * reason, so we can just set the reason string to what was given and set the
1640 * code to be unknown
1641 */
1642 ast_log(LOG_WARNING, "Unknown redirecting reason '%s', defaulting to unknown\n", val);
1644 redirecting.orig_reason.str = val;
1645 set_it(chan, &redirecting, NULL);
1646 } else {
1647 redirecting.orig_reason.code = reason;
1648 redirecting.orig_reason.str = "";
1649 set_it(chan, &redirecting, NULL);
1650 }
1651 } else {
1652 status = party_id_write(&redirecting.orig, member.argc - 1, member.subnames + 1,
1653 value);
1654 switch (status) {
1655 case ID_FIELD_VALID:
1656 set_it(chan, &redirecting, NULL);
1657 break;
1658 case ID_FIELD_INVALID:
1659 break;
1660 default:
1661 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1662 break;
1663 }
1664 ast_party_redirecting_free(&redirecting);
1665 }
1666 } else if (!strcasecmp("from", member.subnames[0])) {
1667 status = party_id_write(&redirecting.from, member.argc - 1, member.subnames + 1,
1668 value);
1669 switch (status) {
1670 case ID_FIELD_VALID:
1671 set_it(chan, &redirecting, NULL);
1672 break;
1673 case ID_FIELD_INVALID:
1674 break;
1675 default:
1676 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1677 break;
1678 }
1679 ast_party_redirecting_free(&redirecting);
1680 } else if (!strcasecmp("to", member.subnames[0])) {
1681 status = party_id_write(&redirecting.to, member.argc - 1, member.subnames + 1, value);
1682 switch (status) {
1683 case ID_FIELD_VALID:
1684 set_it(chan, &redirecting, NULL);
1685 break;
1686 case ID_FIELD_INVALID:
1687 break;
1688 default:
1689 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1690 break;
1691 }
1692 ast_party_redirecting_free(&redirecting);
1693 } else if (member.argc == 1 && !strncasecmp("pres", member.subnames[0], 4)) {
1694 int pres;
1695
1698
1699 if (('0' <= val[0]) && (val[0] <= '9')) {
1700 pres = atoi(val);
1701 } else {
1703 }
1704
1705 if (pres < 0) {
1707 "Unknown redirecting combined presentation '%s', value unchanged\n", val);
1708 } else {
1709 redirecting.from.name.presentation = pres;
1710 redirecting.from.number.presentation = pres;
1711 redirecting.to.name.presentation = pres;
1712 redirecting.to.number.presentation = pres;
1713 set_it(chan, &redirecting, NULL);
1714 }
1715 } else if (member.argc == 1 && !strcasecmp("reason", member.subnames[0])) {
1716 int reason;
1717
1720
1721 if (('0' <= val[0]) && (val[0] <= '9')) {
1722 reason = atoi(val);
1723 } else {
1725 }
1726
1727 if (reason < 0) {
1728 /* The argument passed into the function does not correspond to a pre-defined
1729 * reason, so we can just set the reason string to what was given and set the
1730 * code to be unknown
1731 */
1732 ast_log(LOG_WARNING, "Unknown redirecting reason '%s', defaulting to unknown\n", val);
1734 redirecting.reason.str = val;
1735 set_it(chan, &redirecting, NULL);
1736 } else {
1737 redirecting.reason.code = reason;
1738 redirecting.reason.str = "";
1739 set_it(chan, &redirecting, NULL);
1740 }
1741 } else if (member.argc == 1 && !strcasecmp("count", member.subnames[0])) {
1744
1745 if (('0' <= val[0]) && (val[0] <= '9')) {
1746 redirecting.count = atoi(val);
1747 set_it(chan, &redirecting, NULL);
1748 } else {
1749 ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
1750 }
1751 } else if (1 < member.argc && !strcasecmp("priv", member.subnames[0])) {
1752 if (!strcasecmp("orig", member.subnames[1])) {
1753 status = party_id_write(&redirecting.priv_orig, member.argc - 2, member.subnames + 2,
1754 value);
1755 switch (status) {
1756 case ID_FIELD_VALID:
1757 set_it(chan, &redirecting, NULL);
1758 break;
1759 case ID_FIELD_INVALID:
1760 break;
1761 default:
1762 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1763 break;
1764 }
1765 ast_party_redirecting_free(&redirecting);
1766 } else if (!strcasecmp("from", member.subnames[1])) {
1767 status = party_id_write(&redirecting.priv_from, member.argc - 2, member.subnames + 2,
1768 value);
1769 switch (status) {
1770 case ID_FIELD_VALID:
1771 set_it(chan, &redirecting, NULL);
1772 break;
1773 case ID_FIELD_INVALID:
1774 break;
1775 default:
1776 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1777 break;
1778 }
1779 ast_party_redirecting_free(&redirecting);
1780 } else if (!strcasecmp("to", member.subnames[1])) {
1781 status = party_id_write(&redirecting.priv_to, member.argc - 2, member.subnames + 2, value);
1782 switch (status) {
1783 case ID_FIELD_VALID:
1784 set_it(chan, &redirecting, NULL);
1785 break;
1786 case ID_FIELD_INVALID:
1787 break;
1788 default:
1789 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1790 break;
1791 }
1792 ast_party_redirecting_free(&redirecting);
1793 } else {
1794 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1795 }
1796 } else {
1797 ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
1798 }
1799
1800 return 0;
1801}
@ AST_REDIRECTING_REASON_UNKNOWN
Definition: callerid.h:499
int ast_redirecting_reason_parse(const char *data)
Convert redirecting reason text code to value (used in config file parsing)
Definition: callerid.c:1423
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
Definition: channel.c:9124
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation.
Definition: channel.c:2120
void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Indicate that the redirecting id has changed.
Definition: channel.c:10289
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
Definition: channel.c:2146
static const struct ast_app_option redirecting_opts[128]
#define LOG_WARNING
struct ast_party_name name
Subscriber name.
Definition: channel.h:342
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:279
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:297
int code
enum AST_REDIRECTING_REASON value for redirection
Definition: channel.h:512
char * str
a string value for the redirecting reason
Definition: channel.h:509
Indicate what information in ast_party_redirecting should be set.
Definition: channel.h:557

References args, ARRAY_LEN, ast_app_parse_options(), ast_channel_lock, ast_channel_redirecting(), ast_channel_set_redirecting(), ast_channel_unlock, ast_channel_update_redirecting(), ast_log, AST_NONSTANDARD_APP_ARGS, ast_parse_caller_presentation(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_redirecting_reason_parse(), AST_REDIRECTING_REASON_UNKNOWN, ast_skip_blanks(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_test_flag, ast_trim_blanks(), ast_party_redirecting_reason::code, ast_party_redirecting::count, ast_party_redirecting::from, ID_FIELD_INVALID, ID_FIELD_VALID, LOG_ERROR, LOG_WARNING, ast_party_id::name, NULL, ast_party_id::number, ast_party_redirecting::orig, ast_party_redirecting::orig_reason, party_id_write(), ast_party_name::presentation, ast_party_number::presentation, ast_party_redirecting::priv_from, ast_party_redirecting::priv_orig, ast_party_redirecting::priv_to, ast_party_redirecting::reason, REDIRECTING_OPT_ARG_ARRAY_SIZE, REDIRECTING_OPT_INHIBIT, redirecting_opts, status, ast_party_redirecting_reason::str, ast_party_redirecting::to, update(), and value.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1829 of file func_callerid.c.

1830{
1834 return 0;
1835}
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

References ast_custom_function_unregister(), callerid_function, connectedline_function, and redirecting_function.

Referenced by load_module().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Party ID related dialplan functions (Caller-ID, Connected-line, Redirecting)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 1861 of file func_callerid.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1861 of file func_callerid.c.

◆ callerid_function

struct ast_custom_function callerid_function
static

Definition at line 1803 of file func_callerid.c.

Referenced by load_module(), and unload_module().

◆ connectedline_function

struct ast_custom_function connectedline_function
static
Initial value:
= {
.name = "CONNECTEDLINE",
}
static int connectedline_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int connectedline_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1810 of file func_callerid.c.

Referenced by load_module(), and unload_module().

◆ connectedline_opts

const struct ast_app_option connectedline_opts[128] = { [ 'i' ] = { .flag = CONNECTED_LINE_OPT_INHIBIT }, }
static

Definition at line 489 of file func_callerid.c.

Referenced by connectedline_write().

◆ redirecting_function

struct ast_custom_function redirecting_function
static
Initial value:
= {
.name = "REDIRECTING",
}
static int redirecting_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int redirecting_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)

Definition at line 1816 of file func_callerid.c.

Referenced by load_module(), and unload_module().

◆ redirecting_opts

const struct ast_app_option redirecting_opts[128] = { [ 'i' ] = { .flag = REDIRECTING_OPT_INHIBIT }, }
static

Definition at line 503 of file func_callerid.c.

Referenced by redirecting_write().