Merged revisions 51341 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  */
22
23 #include "asterisk.h"
24
25 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/types.h>
31
32 #include "asterisk/module.h"
33 #include "asterisk/channel.h"
34 #include "asterisk/pbx.h"
35 #include "asterisk/logger.h"
36 #include "asterisk/utils.h"
37 #include "asterisk/app.h"
38 #include "asterisk/options.h"
39 #include "asterisk/callerid.h"
40
41 static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
42                          char *buf, size_t len)
43 {
44         char *opt = data;
45
46         /* XXX we are not always clearing the buffer. Is this correct ? */
47         if (strchr(opt, '|')) {
48                 char name[80], num[80];
49
50                 data = strsep(&opt, "|");
51                 ast_callerid_split(opt, name, sizeof(name), num, sizeof(num));
52
53                 if (!strncasecmp("all", data, 3)) {
54                         snprintf(buf, len, "\"%s\" <%s>", name, num);
55                 } else if (!strncasecmp("name", data, 4)) {
56                         ast_copy_string(buf, name, len);
57                 } else if (!strncasecmp("num", data, 3)) {
58                         ast_copy_string(buf, num, len);
59                 } else {
60                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
61                 }
62         } else {
63                 if (!strncasecmp("all", data, 3)) {
64                         snprintf(buf, len, "\"%s\" <%s>",
65                                  S_OR(chan->cid.cid_name, ""),
66                                  S_OR(chan->cid.cid_num, ""));
67                 } else if (!strncasecmp("name", data, 4)) {
68                         if (chan->cid.cid_name) {
69                                 ast_copy_string(buf, chan->cid.cid_name, len);
70                         }
71                 } else if (!strncasecmp("num", data, 3)) {
72                         if (chan->cid.cid_num) {
73                                 ast_copy_string(buf, chan->cid.cid_num, len);
74                         }
75                 } else if (!strncasecmp("ani", data, 3)) {
76                         if (chan->cid.cid_ani) {
77                                 ast_copy_string(buf, chan->cid.cid_ani, len);
78                         }
79                 } else if (!strncasecmp("dnid", data, 4)) {
80                         if (chan->cid.cid_dnid) {
81                                 ast_copy_string(buf, chan->cid.cid_dnid, len);
82                         }
83                 } else if (!strncasecmp("rdnis", data, 5)) {
84                         if (chan->cid.cid_rdnis) {
85                                 ast_copy_string(buf, chan->cid.cid_rdnis, len);
86                         }
87                 } else if (!strncasecmp("pres", data, 4)) {
88                         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
89                 } else if (!strncasecmp("ton", data, 3)) {
90                         snprintf(buf, len, "%d", chan->cid.cid_ton);
91                 } else {
92                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
93                 }
94         }
95
96         return 0;
97 }
98
99 static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
100                           const char *value)
101 {
102         if (!value)
103                 return -1;
104
105         if (!strncasecmp("all", data, 3)) {
106                 char name[256];
107                 char num[256];
108
109                 if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
110                         ast_set_callerid(chan, num, name, num);
111         } else if (!strncasecmp("name", data, 4)) {
112                 ast_set_callerid(chan, NULL, value, NULL);
113         } else if (!strncasecmp("num", data, 3)) { 
114                 ast_set_callerid(chan, value, NULL, NULL);
115         } else if (!strncasecmp("ani", data, 3)) {
116                 ast_set_callerid(chan, NULL, NULL, value);
117         } else if (!strncasecmp("dnid", data, 4)) {
118                 /* do we need to lock chan here? */
119                 if (chan->cid.cid_dnid)
120                         free(chan->cid.cid_dnid);
121                 chan->cid.cid_dnid = ast_strdup(value);
122         } else if (!strncasecmp("rdnis", data, 5)) {
123                 /* do we need to lock chan here? */
124                 if (chan->cid.cid_rdnis)
125                         free(chan->cid.cid_rdnis);
126                 chan->cid.cid_rdnis = ast_strdup(value);
127         } else if (!strncasecmp("pres", data, 4)) {
128                 int i;
129                 char *s, *val;
130
131                 /* Strip leading spaces */
132                 while ((value[0] == '\t') || (value[0] == ' '))
133                         ++value;
134
135                 val = ast_strdupa(value);
136
137                 /* Strip trailing spaces */
138                 s = val + strlen(val);
139                 while ((s != val) && ((s[-1] == '\t') || (s[-1] == ' ')))
140                         --s;
141                 *s = '\0';
142
143                 if ((val[0] >= '0') && (val[0] <= '9'))
144                         i = atoi(val);
145                 else
146                         i = ast_parse_caller_presentation(val);
147
148                 if (i < 0)
149                         ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
150                 else
151                         chan->cid.cid_pres = i;
152         } else if (!strncasecmp("ton", data, 3)) {
153                 int i = atoi(value);
154                 chan->cid.cid_ton = i;
155         } else {
156                 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
157         }
158
159         return 0;
160 }
161
162 static struct ast_custom_function callerid_function = {
163         .name = "CALLERID",
164         .synopsis = "Gets or sets Caller*ID data on the channel.",
165         .syntax = "CALLERID(datatype[,<optional-CID>])",
166         .desc =
167                 "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
168                 "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\", \"pres\",\n"
169                 "and \"ton\".\n"
170                 "Uses channel callerid by default or optional callerid, if specified.\n",
171         .read = callerid_read,
172         .write = callerid_write,
173 };
174
175 static int unload_module(void)
176 {
177         return ast_custom_function_unregister(&callerid_function);
178 }
179
180 static int load_module(void)
181 {
182         return ast_custom_function_register(&callerid_function);
183 }
184
185 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan function");