~ubuntu-branches/ubuntu/karmic/asterisk/karmic

« back to all changes in this revision

Viewing changes to main/autoservice.c

  • Committer: Bazaar Package Importer
  • Author(s): Faidon Liambotis, Tzafrir Cohen, Faidon Liambotis
  • Date: 2007-12-06 17:20:21 UTC
  • mfrom: (1.1.19 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206172021-pd0wrjirz3os7hia
Tags: 1:1.4.15~dfsg-1
* New upstream release (Closes: #452054)
  - Fix a potential corrupt of voicemail.conf on simultaneous PIN updates
    (Closes: #353227)

[ Tzafrir Cohen ]
* Add some sample/reference config files as documentation.
* Provide asterisk-bristuff for upgrading from Etch.
* Move libc-client to not be last, so debian/backports/xorcom.etch would
  still work.

[ Faidon Liambotis ]
* Really enable the libcap/ToS functionality; the previous patch didn't
  enable the functionality, even though the code and the libcap.so
  dependency were there. (Closes: #454342)
* Fix a minor issue with init script's stop target when running with
  safe_asterisk.
* Add chan_vpb, adding support for VoiceTronix OpenSwitch and OpenLine
  cards. (Closes: #396499)
* Fix debian/watch by using a pkg-voip wrapper to avoid upstream's silly
  redirections. (Closes: #449706)
* Use DEBVERSION as asterisk's version string.
* Disable the MD5 build sum that breaks all out-of-tree plugins (duh!).
* Create /usr/local/share/asterisk/sounds to put all site-specific
  non-modifiable sounds.
* Add a note about bugs.debian.org to the banner.
* Add noload for res_config_* since loading them results in errors and
  doesn't provide any functionality.
* News entries were added but we never shipped the file; ship NEWS.Debian.
* Add an entry to NEWS.Debian warning users about app_voicemail_*.so
  (Closes: #452596)
* Provide options in /etc/default/asterisk for configuring safe_asterisk.
  (Closes: #381786)

[ Tzafrir Cohen ]
* Provide a custom sounds directory under /var/lib - user-modifieble at
  runtime and hence not under /usr. (Closes: #337209)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
#include "asterisk.h"
27
27
 
28
 
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 44378 $")
 
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision: 89886 $")
29
29
 
30
30
#include <stdio.h>
31
31
#include <stdlib.h>
54
54
 
55
55
struct asent {
56
56
        struct ast_channel *chan;
 
57
        /*! This gets incremented each time autoservice gets started on the same
 
58
         *  channel.  It will ensure that it doesn't actually get stopped until 
 
59
         *  it gets stopped for the last time. */
 
60
        unsigned int use_count;
 
61
        AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
57
62
        AST_LIST_ENTRY(asent) list;
58
63
};
59
64
 
83
88
 
84
89
                chan = ast_waitfor_n(mons, x, &ms);
85
90
                if (chan) {
86
 
                        /* Read and ignore anything that occurs */
87
91
                        struct ast_frame *f = ast_read(chan);
 
92
        
 
93
                        if (!f)
 
94
                                continue;
 
95
                        
 
96
                        /* Do not add a default entry in this switch statement.  Each new
 
97
                         * frame type should be addressed directly as to whether it should
 
98
                         * be queued up or not. */
 
99
                        switch (f->frametype) {
 
100
                        /* Save these frames */
 
101
                        case AST_FRAME_DTMF_BEGIN:
 
102
                        case AST_FRAME_DTMF_END:
 
103
                        case AST_FRAME_CONTROL:
 
104
                        case AST_FRAME_TEXT:
 
105
                        case AST_FRAME_IMAGE:
 
106
                        case AST_FRAME_HTML:
 
107
                        {
 
108
                                struct ast_frame *dup_f;
 
109
 
 
110
                                AST_LIST_LOCK(&aslist);
 
111
                                AST_LIST_TRAVERSE(&aslist, as, list) {
 
112
                                        if (as->chan != chan)
 
113
                                                continue;
 
114
                                        if ((dup_f = ast_frdup(f)))
 
115
                                                AST_LIST_INSERT_TAIL(&as->dtmf_frames, dup_f, frame_list);
 
116
                                }
 
117
                                AST_LIST_UNLOCK(&aslist);
 
118
                        }
 
119
 
 
120
                        /* Throw these frames away */
 
121
                        case AST_FRAME_VOICE:
 
122
                        case AST_FRAME_VIDEO:
 
123
                        case AST_FRAME_NULL:
 
124
                        case AST_FRAME_IAX:
 
125
                        case AST_FRAME_CNG:
 
126
                        case AST_FRAME_MODEM:
 
127
                                break;
 
128
                        }
 
129
 
88
130
                        if (f)
89
131
                                ast_frfree(f);
90
132
                }
97
139
{
98
140
        int res = -1;
99
141
        struct asent *as;
 
142
 
100
143
        AST_LIST_LOCK(&aslist);
101
144
 
102
145
        /* Check if the channel already has autoservice */
103
146
        AST_LIST_TRAVERSE(&aslist, as, list) {
104
 
                if (as->chan == chan)
 
147
                if (as->chan == chan) {
 
148
                        as->use_count++;
105
149
                        break;
 
150
                }
106
151
        }
107
152
 
108
153
        /* If not, start autoservice on channel */
109
154
        if (!as && (as = ast_calloc(1, sizeof(*as)))) {
110
155
                as->chan = chan;
 
156
                as->use_count = 1;
111
157
                AST_LIST_INSERT_HEAD(&aslist, as, list);
112
158
                res = 0;
113
159
                if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
122
168
                                pthread_kill(asthread, SIGURG);
123
169
                }
124
170
        }
 
171
 
125
172
        AST_LIST_UNLOCK(&aslist);
 
173
 
126
174
        return res;
127
175
}
128
176
 
130
178
{
131
179
        int res = -1;
132
180
        struct asent *as;
 
181
        AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
 
182
        struct ast_frame *f;
 
183
        int removed = 1;
 
184
 
 
185
        AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
133
186
 
134
187
        AST_LIST_LOCK(&aslist);
135
188
        AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {       
136
189
                if (as->chan == chan) {
 
190
                        as->use_count--;
 
191
                        if (as->use_count) {
 
192
                                removed = 0;
 
193
                                break;
 
194
                        }
137
195
                        AST_LIST_REMOVE_CURRENT(&aslist, list);
 
196
                        AST_LIST_APPEND_LIST(&dtmf_frames, &as->dtmf_frames, frame_list);
138
197
                        free(as);
139
198
                        if (!chan->_softhangup)
140
199
                                res = 0;
143
202
        }
144
203
        AST_LIST_TRAVERSE_SAFE_END
145
204
 
146
 
        if (asthread != AST_PTHREADT_NULL) 
 
205
        if (removed && asthread != AST_PTHREADT_NULL) 
147
206
                pthread_kill(asthread, SIGURG);
 
207
 
148
208
        AST_LIST_UNLOCK(&aslist);
149
209
 
 
210
        if (!removed)
 
211
                return 0;
 
212
 
150
213
        /* Wait for it to un-block */
151
 
        while(ast_test_flag(chan, AST_FLAG_BLOCKING))
 
214
        while (ast_test_flag(chan, AST_FLAG_BLOCKING))
152
215
                usleep(1000);
 
216
 
 
217
        while ((f = AST_LIST_REMOVE_HEAD(&dtmf_frames, frame_list))) {
 
218
                ast_queue_frame(chan, f);
 
219
                ast_frfree(f);
 
220
        }
 
221
 
153
222
        return res;
154
223
}