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