e53097f3b43dfac7e1ed355f3ca290f919df8f14
[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                 if (!strncasecmp("all", data, 3)) {
76                         snprintf(buf, len, "\"%s\" <%s>",
77                                  S_OR(chan->cid.cid_name, ""),
78                                  S_OR(chan->cid.cid_num, ""));
79                 } else if (!strncasecmp("name", data, 4)) {
80                         if (chan->cid.cid_name) {
81                                 ast_copy_string(buf, chan->cid.cid_name, len);
82                         }
83                 } else if (!strncasecmp("num", data, 3)) {
84                         if (chan->cid.cid_num) {
85                                 ast_copy_string(buf, chan->cid.cid_num, len);
86                         }
87                 } else if (!strncasecmp("ani", data, 3)) {
88                         if (!strncasecmp(data + 3, "2", 1)) {
89                                 snprintf(buf, len, "%d", chan->cid.cid_ani2);
90                         } else if (chan->cid.cid_ani) {
91                                 ast_copy_string(buf, chan->cid.cid_ani, len);
92                         }
93                 } else if (!strncasecmp("dnid", data, 4)) {
94                         if (chan->cid.cid_dnid) {
95                                 ast_copy_string(buf, chan->cid.cid_dnid, len);
96                         }
97                 } else if (!strncasecmp("rdnis", data, 5)) {
98                         if (chan->cid.cid_rdnis) {
99                                 ast_copy_string(buf, chan->cid.cid_rdnis, len);
100                         }
101                 } else if (!strncasecmp("pres", data, 4)) {
102                         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
103                 } else if (!strncasecmp("ton", data, 3)) {
104                         snprintf(buf, len, "%d", chan->cid.cid_ton);
105                 } else {
106                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
107                 }
108         }
109
110         return 0;
111 }
112
113 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
114                           const char *value)
115 {
116         if (!value || !chan)
117                 return -1;
118
119         if (!strncasecmp("all", data, 3)) {
120                 char name[256];
121                 char num[256];
122
123                 if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
124                         ast_set_callerid(chan, num, name, num);
125         } else if (!strncasecmp("name", data, 4)) {
126                 ast_set_callerid(chan, NULL, value, NULL);
127         } else if (!strncasecmp("num", data, 3)) { 
128                 ast_set_callerid(chan, value, NULL, NULL);
129         } else if (!strncasecmp("ani", data, 3)) {
130                 if (!strncasecmp(data + 3, "2", 1)) {
131                         int i = atoi(value);
132                         chan->cid.cid_ani2 = i;
133                 } else
134                         ast_set_callerid(chan, NULL, NULL, value);
135         } else if (!strncasecmp("dnid", data, 4)) {
136                 /* do we need to lock chan here? */
137                 if (chan->cid.cid_dnid)
138                         ast_free(chan->cid.cid_dnid);
139                 chan->cid.cid_dnid = ast_strdup(value);
140         } else if (!strncasecmp("rdnis", data, 5)) {
141                 /* do we need to lock chan here? */
142                 if (chan->cid.cid_rdnis)
143                         ast_free(chan->cid.cid_rdnis);
144                 chan->cid.cid_rdnis = ast_strdup(value);
145         } else if (!strncasecmp("pres", data, 4)) {
146                 int i;
147                 char *s, *val;
148
149                 /* Strip leading spaces */
150                 while ((value[0] == '\t') || (value[0] == ' '))
151                         ++value;
152
153                 val = ast_strdupa(value);
154
155                 /* Strip trailing spaces */
156                 s = val + strlen(val);
157                 while ((s != val) && ((s[-1] == '\t') || (s[-1] == ' ')))
158                         --s;
159                 *s = '\0';
160
161                 if ((val[0] >= '0') && (val[0] <= '9'))
162                         i = atoi(val);
163                 else
164                         i = ast_parse_caller_presentation(val);
165
166                 if (i < 0)
167                         ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
168                 else
169                         chan->cid.cid_pres = i;
170         } else if (!strncasecmp("ton", data, 3)) {
171                 int i = atoi(value);
172                 chan->cid.cid_ton = i;
173         } else {
174                 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
175         }
176
177         return 0;
178 }
179
180 static struct ast_custom_function callerid_function = {
181         .name = "CALLERID",
182         .synopsis = "Gets or sets Caller*ID data on the channel.",
183         .syntax = "CALLERID(datatype[,<optional-CID>])",
184         .desc =
185                 "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
186                 "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\", \"pres\",\n"
187                 "and \"ton\".\n"
188                 "Uses channel callerid by default or optional callerid, if specified.\n",
189         .read = callerid_read,
190         .write = callerid_write,
191 };
192
193 static struct ast_custom_function callerpres_function = {
194         .name = "CALLERPRES",
195         .synopsis = "Gets or sets Caller*ID presentation on the channel.",
196         .syntax = "CALLERPRES()",
197         .desc =
198 "Gets or sets Caller*ID presentation on the channel.  The following values\n"
199 "are valid:\n"
200 "      allowed_not_screened    : Presentation Allowed, Not Screened\n"
201 "      allowed_passed_screen   : Presentation Allowed, Passed Screen\n" 
202 "      allowed_failed_screen   : Presentation Allowed, Failed Screen\n" 
203 "      allowed                 : Presentation Allowed, Network Number\n"
204 "      prohib_not_screened     : Presentation Prohibited, Not Screened\n" 
205 "      prohib_passed_screen    : Presentation Prohibited, Passed Screen\n"
206 "      prohib_failed_screen    : Presentation Prohibited, Failed Screen\n"
207 "      prohib                  : Presentation Prohibited, Network Number\n"
208 "      unavailable             : Number Unavailable\n",
209         .read = callerpres_read,
210         .write = callerpres_write,
211 };
212
213 static int unload_module(void)
214 {
215         int res = ast_custom_function_unregister(&callerpres_function);
216         res |= ast_custom_function_unregister(&callerid_function);
217         return res;
218 }
219
220 static int load_module(void)
221 {
222         int res = ast_custom_function_register(&callerpres_function);
223         res |= ast_custom_function_register(&callerid_function);
224         return res;
225 }
226
227 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan functions");