Extend CALLERID() function for "pres" and "ton" values
[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, 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                            !strncasecmp("number", data, 6)) {
59
60                         ast_copy_string(buf, num, len);
61                 } else {
62                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
63                 }
64         } else {
65                 if (!strncasecmp("all", data, 3)) {
66                         snprintf(buf, len, "\"%s\" <%s>",
67                                  S_OR(chan->cid.cid_name, ""),
68                                  S_OR(chan->cid.cid_num, ""));
69                 } else if (!strncasecmp("name", data, 4)) {
70                         if (chan->cid.cid_name) {
71                                 ast_copy_string(buf, chan->cid.cid_name, len);
72                         }
73                 } else if (!strncasecmp("num", data, 3)
74                                    || !strncasecmp("number", data, 6)) {
75                         if (chan->cid.cid_num) {
76                                 ast_copy_string(buf, chan->cid.cid_num, len);
77                         }
78                 } else if (!strncasecmp("ani", data, 3)) {
79                         if (chan->cid.cid_ani) {
80                                 ast_copy_string(buf, chan->cid.cid_ani, len);
81                         }
82                 } else if (!strncasecmp("dnid", data, 4)) {
83                         if (chan->cid.cid_dnid) {
84                                 ast_copy_string(buf, chan->cid.cid_dnid, len);
85                         }
86                 } else if (!strncasecmp("rdnis", data, 5)) {
87                         if (chan->cid.cid_rdnis) {
88                                 ast_copy_string(buf, chan->cid.cid_rdnis, len);
89                         }
90                 } else if (!strncasecmp("pres", data, 4)) {
91                         ast_copy_string(buf, ast_named_caller_presentation(chan->cid.cid_pres), len);
92                 } else if (!strncasecmp("ton", data, 3)) {
93                         snprintf(buf, len, "%d", chan->cid.cid_ton);
94                 } else {
95                         ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
96                 }
97         }
98
99         return 0;
100 }
101
102 static int callerid_write(struct ast_channel *chan, char *cmd, char *data,
103                           const char *value)
104 {
105         if (!value)
106                 return -1;
107
108         if (!strncasecmp("all", data, 3)) {
109                 char name[256];
110                 char num[256];
111
112                 if (!ast_callerid_split(value, name, sizeof(name), num, sizeof(num)))
113                         ast_set_callerid(chan, num, name, num);
114         } else if (!strncasecmp("name", data, 4)) {
115                 ast_set_callerid(chan, NULL, value, NULL);
116         } else if (!strncasecmp("num", data, 3) ||
117                    !strncasecmp("number", data, 6)) {
118                 ast_set_callerid(chan, value, NULL, NULL);
119         } else if (!strncasecmp("ani", data, 3)) {
120                 ast_set_callerid(chan, NULL, NULL, value);
121         } else if (!strncasecmp("dnid", data, 4)) {
122                 /* do we need to lock chan here? */
123                 if (chan->cid.cid_dnid)
124                         free(chan->cid.cid_dnid);
125                 chan->cid.cid_dnid = ast_strdup(value);
126         } else if (!strncasecmp("rdnis", data, 5)) {
127                 /* do we need to lock chan here? */
128                 if (chan->cid.cid_rdnis)
129                         free(chan->cid.cid_rdnis);
130                 chan->cid.cid_rdnis = ast_strdup(value);
131         } else if (!strncasecmp("pres", data, 4)) {
132                 int i;
133                 char *s, *val;
134
135                 /* Strip leading spaces */
136                 while ((value[0] == '\t') || (value[0] == ' '))
137                         ++value;
138
139                 val = ast_strdupa(value);
140
141                 /* Strip trailing spaces */
142                 s = val + strlen(val);
143                 while ((s != val) && ((s[-1] == '\t') || (s[-1] == ' ')))
144                         --s;
145                 *s = '\0';
146
147                 if ((val[0] >= '0') && (val[0] <= '9'))
148                         i = atoi(val);
149                 else
150                         i = ast_parse_caller_presentation(val);
151
152                 if (i < 0)
153                         ast_log(LOG_ERROR, "Unknown calling number presentation '%s', value unchanged\n", val);
154                 else
155                         chan->cid.cid_pres = i;
156         } else if (!strncasecmp("ton", data, 3)) {
157                 int i = atoi(value);
158                 chan->cid.cid_ton = i;
159         } else {
160                 ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
161         }
162
163         return 0;
164 }
165
166 static struct ast_custom_function callerid_function = {
167         .name = "CALLERID",
168         .synopsis = "Gets or sets Caller*ID data on the channel.",
169         .syntax = "CALLERID(datatype[,<optional-CID>])",
170         .desc =
171                 "Gets or sets Caller*ID data on the channel.  The allowable datatypes\n"
172                 "are \"all\", \"name\", \"num\", \"ANI\", \"DNID\", \"RDNIS\", \"pres\",\n"
173                 "and \"ton\".\n"
174                 "Uses channel callerid by default or optional callerid, if specified.\n",
175         .read = callerid_read,
176         .write = callerid_write,
177 };
178
179 static int unload_module(void)
180 {
181         return ast_custom_function_unregister(&callerid_function);
182 }
183
184 static int load_module(void)
185 {
186         return ast_custom_function_register(&callerid_function);
187 }
188
189 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Caller ID related dialplan function");