Merged revisions 140670 via svnmerge from
[asterisk/asterisk.git] / funcs / func_callerid.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999-2006, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Caller ID related dialplan functions
20  * 
21  * \ingroup functions
22  */
23
24 #include "asterisk.h"
25
26 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
27
28 #include "asterisk/module.h"
29 #include "asterisk/channel.h"
30 #include "asterisk/pbx.h"
31 #include "asterisk/utils.h"
32 #include "asterisk/app.h"
33 #include "asterisk/callerid.h"
34
35 static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
36 {
37         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
38         return 0;
39 }
40
41 static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
42 {
43         int pres = ast_parse_caller_presentation(value);
44         if (pres < 0)
45                 ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show function CALLERPRES')\n", value);
46         else
47                 chan->cid.cid_pres = pres;
48         return 0;
49 }
50
51 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
52                          char *buf, size_t len)
53 {
54         char *opt = data;
55
56         if (!chan)
57                 return -1;
58
59         if (strchr(opt, ',')) {
60                 char name[80], num[80];
61
62                 data = strsep(&opt, ",");
63                 ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
64
65                 if (!strncasecmp("all", data, 3)) {
66                         snprintf(buf, len, "\"%s\" <%s>", name, num);
67                 } else if (!strncasecmp("name", data, 4)) {
68                         ast_copy_string(buf, name, len);
69                 } else if (!strncasecmp("num", data, 3)) {
70                         ast_copy_string(buf, num, len);
71                 } else {
72                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
73                 }
74         } else {
75                 ast_channel_lock(chan);
76
77                 if (!strncasecmp("all", data, 3)) {
78                         snprintf(buf, len, "\"%s\" <%s>",
79                                  S_OR(chan->cid.cid_name, ""),
80                                  S_OR(chan->cid.cid_num, ""));
81                 } else if (!strncasecmp("name", data, 4)) {
82                         if (chan->cid.cid_name) {
83                                 ast_copy_string(buf, chan->cid.cid_name, len);
84                         }
85                 } else if (!strncasecmp("num", data, 3)) {
86                         if (chan->cid.cid_num) {
87                                 ast_copy_string(buf, chan->cid.cid_num, len);
88                         }
89                 } else if (!strncasecmp("ani", data, 3)) {
90                         if (!strncasecmp(data + 3, "2", 1)) {
91                                 snprintf(buf, len, "%d", chan->cid.cid_ani2);
92                         } else if (chan->cid.cid_ani) {
93                                 ast_copy_string(buf, chan->cid.cid_ani, len);
94                         }
95                 } else if (!strncasecmp("dnid", data, 4)) {
96                         if (chan->cid.cid_dnid) {
97                                 ast_copy_string(buf, chan->cid.cid_dnid, len);
98                         }
99                 } else if (!strncasecmp("rdnis", data, 5)) {
100                         if (chan->cid.cid_rdnis) {
101                                 ast_copy_string(buf, chan->cid.cid_rdnis, len);
102                         }
103                 } else if (!strncasecmp("pres", data, 4)) {
104                         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
105                 } else if (!strncasecmp("ton", data, 3)) {
106                         snprintf(buf, len, "%d", chan->cid.cid_ton);
107                 } else {
108                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
109                 }
110
111                 ast_channel_unlock(chan);
112         }
113
114         return 0;
115 }
116
117 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
118                           const char *value)
119 {
120         if (!value || !chan)
121                 return -1;
122
123         if (!strncasecmp("all", data, 3)) {
124                 char name[256];
125                 char num[256];
126
127                 if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
128                         ast_set_callerid(chan, num, name, num);
129         } else if (!strncasecmp("name", data, 4)) {
130                 ast_set_callerid(chan, NULL, value, NULL);
131         } else if (!strncasecmp("num", data, 3)) { 
132                 ast_set_callerid(chan, value, NULL, NULL);
133         } else if (!strncasecmp("ani", data, 3)) {
134                 if (!strncasecmp(data + 3, "2", 1)) {
135                         int i = atoi(value);
136                         chan->cid.cid_ani2 = i;
137                 } else
138                         ast_set_callerid(chan, NULL, NULL, value);
139         } else if (!strncasecmp("dnid", data, 4)) {
140                 ast_channel_lock(chan);
141                 if (chan->cid.cid_dnid)
142                         ast_free(chan->cid.cid_dnid);
143                 chan->cid.cid_dnid = ast_strdup(value);
144                 ast_channel_unlock(chan);
145         } else if (!strncasecmp("rdnis", data, 5)) {
146                 ast_channel_lock(chan);
147                 if (chan->cid.cid_rdnis)
148                         ast_free(chan->cid.cid_rdnis);
149                 chan->cid.cid_rdnis = ast_strdup(value);
150                 ast_channel_unlock(chan);
151         } else if (!strncasecmp("pres", data, 4)) {
152                 int i;
153                 char *s, *val;
154
155                 /* Strip leading spaces */
156                 while ((value[0] == '\t') || (value[0] == ' '))
157                         ++value;
158
159                 val = ast_strdupa(value);
160
161                 /* Strip trailing spaces */
162                 s = val + strlen(val);
163                 while ((s != val) && ((s[-1] == '\t') || (s[-1] == ' ')))
164                         --s;
165                 *s = '\0';
166
167                 if ((val[0] >= '0') && (val[0] <= '9'))
168                         i = atoi(val);
169                 else
170                         i = ast_parse_caller_presentation(val);
171
172                 if (i < 0)
173                         ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
174                 else
175                         chan->cid.cid_pres = i;
176         } else if (!strncasecmp("ton", data, 3)) {
177                 int i = atoi(value);
178                 chan->cid.cid_ton = i;
179         } else {
180                 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
181         }
182
183         return 0;
184 }
185
186 static struct ast_custom_function callerid_function = {
187         .name = "CALLERID",
188         .synopsis = "Gets or sets Caller*ID data on the channel.",
189         .syntax = "CALLERID(datatype[,<optional-CID>])",
190         .desc =
191                 "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
192                 "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\", \"pres\",\n"
193                 "and \"ton\".\n"
194                 "Uses channel callerid by default or optional callerid, if specified.\n",
195         .read = callerid_read,
196         .write = callerid_write,
197 };
198
199 static struct ast_custom_function callerpres_function = {
200         .name = "CALLERPRES",
201         .synopsis = "Gets or sets Caller*ID presentation on the channel.",
202         .syntax = "CALLERPRES()",
203         .desc =
204 "Gets or sets Caller*ID presentation on the channel.  The following values\n"
205 "are valid:\n"
206 "      allowed_not_screened    : Presentation Allowed, Not Screened\n"
207 "      allowed_passed_screen   : Presentation Allowed, Passed Screen\n" 
208 "      allowed_failed_screen   : Presentation Allowed, Failed Screen\n" 
209 "      allowed                 : Presentation Allowed, Network Number\n"
210 "      prohib_not_screened     : Presentation Prohibited, Not Screened\n" 
211 "      prohib_passed_screen    : Presentation Prohibited, Passed Screen\n"
212 "      prohib_failed_screen    : Presentation Prohibited, Failed Screen\n"
213 "      prohib                  : Presentation Prohibited, Network Number\n"
214 "      unavailable             : Number Unavailable\n",
215         .read = callerpres_read,
216         .write = callerpres_write,
217 };
218
219 static int unload_module(void)
220 {
221         int res = ast_custom_function_unregister(&callerpres_function);
222         res |= ast_custom_function_unregister(&callerid_function);
223         return res;
224 }
225
226 static int load_module(void)
227 {
228         int res = ast_custom_function_register(&callerpres_function);
229         res |= ast_custom_function_register(&callerid_function);
230         return res;
231 }
232
233 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan functions");