Blocked revisions 53878 via svnmerge
[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 <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/types.h>
32
33 #include "asterisk/module.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/pbx.h"
36 #include "asterisk/logger.h"
37 #include "asterisk/utils.h"
38 #include "asterisk/app.h"
39 #include "asterisk/options.h"
40 #include "asterisk/callerid.h"
41
42 static int callerpres_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
43 {
44         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
45         return 0;
46 }
47
48 static int callerpres_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
49 {
50         int pres = ast_parse_caller_presentation(value);
51         if (pres < 0)
52                 ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show function CALLERPRES')\n", value);
53         else
54                 chan->cid.cid_pres = pres;
55         return 0;
56 }
57
58 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
59                          char *buf, size_t len)
60 {
61         char *opt = data;
62
63         /* XXX we are not always clearing the buffer. Is this correct ? */
64         if (strchr(opt, '|')) {
65                 char name[80], num[80];
66
67                 data = strsep(&opt, "|");
68                 ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
69
70                 if (!strncasecmp("all", data, 3)) {
71                         snprintf(buf, len, "\"%s\" <%s>", name, num);
72                 } else if (!strncasecmp("name", data, 4)) {
73                         ast_copy_string(buf, name, len);
74                 } else if (!strncasecmp("num", data, 3)) {
75                         ast_copy_string(buf, num, len);
76                 } else {
77                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
78                 }
79         } else {
80                 if (!strncasecmp("all", data, 3)) {
81                         snprintf(buf, len, "\"%s\" <%s>",
82                                  S_OR(chan->cid.cid_name, ""),
83                                  S_OR(chan->cid.cid_num, ""));
84                 } else if (!strncasecmp("name", data, 4)) {
85                         if (chan->cid.cid_name) {
86                                 ast_copy_string(buf, chan->cid.cid_name, len);
87                         }
88                 } else if (!strncasecmp("num", data, 3)) {
89                         if (chan->cid.cid_num) {
90                                 ast_copy_string(buf, chan->cid.cid_num, len);
91                         }
92                 } else if (!strncasecmp("ani", data, 3)) {
93                         if (chan->cid.cid_ani) {
94                                 ast_copy_string(buf, chan->cid.cid_ani, len);
95                         }
96                 } else if (!strncasecmp("dnid", data, 4)) {
97                         if (chan->cid.cid_dnid) {
98                                 ast_copy_string(buf, chan->cid.cid_dnid, len);
99                         }
100                 } else if (!strncasecmp("rdnis", data, 5)) {
101                         if (chan->cid.cid_rdnis) {
102                                 ast_copy_string(buf, chan->cid.cid_rdnis, len);
103                         }
104                 } else if (!strncasecmp("pres", data, 4)) {
105                         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
106                 } else if (!strncasecmp("ton", data, 3)) {
107                         snprintf(buf, len, "%d", chan->cid.cid_ton);
108                 } else {
109                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
110                 }
111         }
112
113         return 0;
114 }
115
116 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
117                           const char *value)
118 {
119         if (!value)
120                 return -1;
121
122         if (!strncasecmp("all", data, 3)) {
123                 char name[256];
124                 char num[256];
125
126                 if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
127                         ast_set_callerid(chan, num, name, num);
128         } else if (!strncasecmp("name", data, 4)) {
129                 ast_set_callerid(chan, NULL, value, NULL);
130         } else if (!strncasecmp("num", data, 3)) { 
131                 ast_set_callerid(chan, value, NULL, NULL);
132         } else if (!strncasecmp("ani", data, 3)) {
133                 ast_set_callerid(chan, NULL, NULL, value);
134         } else if (!strncasecmp("dnid", data, 4)) {
135                 /* do we need to lock chan here? */
136                 if (chan->cid.cid_dnid)
137                         free(chan->cid.cid_dnid);
138                 chan->cid.cid_dnid = ast_strdup(value);
139         } else if (!strncasecmp("rdnis", data, 5)) {
140                 /* do we need to lock chan here? */
141                 if (chan->cid.cid_rdnis)
142                         free(chan->cid.cid_rdnis);
143                 chan->cid.cid_rdnis = ast_strdup(value);
144         } else if (!strncasecmp("pres", data, 4)) {
145                 int i;
146                 char *s, *val;
147
148                 /* Strip leading spaces */
149                 while ((value[0] == '\t') || (value[0] == ' '))
150                         ++value;
151
152                 val = ast_strdupa(value);
153
154                 /* Strip trailing spaces */
155                 s = val + strlen(val);
156                 while ((s != val) && ((s[-1] == '\t') || (s[-1] == ' ')))
157                         --s;
158                 *s = '\0';
159
160                 if ((val[0] >= '0') && (val[0] <= '9'))
161                         i = atoi(val);
162                 else
163                         i = ast_parse_caller_presentation(val);
164
165                 if (i < 0)
166                         ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
167                 else
168                         chan->cid.cid_pres = i;
169         } else if (!strncasecmp("ton", data, 3)) {
170                 int i = atoi(value);
171                 chan->cid.cid_ton = i;
172         } else {
173                 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
174         }
175
176         return 0;
177 }
178
179 static struct ast_custom_function callerid_function = {
180         .name = "CALLERID",
181         .synopsis = "Gets or sets Caller*ID data on the channel.",
182         .syntax = "CALLERID(datatype[,<optional-CID>])",
183         .desc =
184                 "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
185                 "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\", \"pres\",\n"
186                 "and \"ton\".\n"
187                 "Uses channel callerid by default or optional callerid, if specified.\n",
188         .read = callerid_read,
189         .write = callerid_write,
190 };
191
192 static struct ast_custom_function callerpres_function = {
193         .name = "CALLERPRES",
194         .synopsis = "Gets or sets Caller*ID presentation on the channel.",
195         .syntax = "CALLERPRES()",
196         .desc =
197 "Gets or sets Caller*ID presentation on the channel.  The following values\n"
198 "are valid:\n"
199 "      allowed_not_screened    : Presentation Allowed, Not Screened\n"
200 "      allowed_passed_screen   : Presentation Allowed, Passed Screen\n" 
201 "      allowed_failed_screen   : Presentation Allowed, Failed Screen\n" 
202 "      allowed                 : Presentation Allowed, Network Number\n"
203 "      prohib_not_screened     : Presentation Prohibited, Not Screened\n" 
204 "      prohib_passed_screen    : Presentation Prohibited, Passed Screen\n"
205 "      prohib_failed_screen    : Presentation Prohibited, Failed Screen\n"
206 "      prohib                  : Presentation Prohibited, Network Number\n"
207 "      unavailable             : Number Unavailable\n",
208         .read = callerpres_read,
209         .write = callerpres_write,
210 };
211
212 static int unload_module(void)
213 {
214         int res = ast_custom_function_unregister(&callerpres_function);
215         res |= ast_custom_function_unregister(&callerid_function);
216         return res;
217 }
218
219 static int load_module(void)
220 {
221         int res = ast_custom_function_register(&callerpres_function);
222         res |= ast_custom_function_register(&callerid_function);
223         return res;
224 }
225
226 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan functions");