4
* An implementation of Common ISDN API 2.0 for Asterisk
6
* ECT transfer the holded call
8
* Copyright (C) 2002, Junghanns.NET GmbH
10
* Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
12
* This program is free software and may be modified and
13
* distributed under the terms of the GNU Public License.
16
#include <asterisk/file.h>
17
#include <asterisk/logger.h>
18
#include <asterisk/channel.h>
19
#include <asterisk/channel_pvt.h>
20
#include <asterisk/pbx.h>
21
#include <asterisk/module.h>
22
#include <asterisk/say.h>
29
#include <linux/capi.h>
31
#include "chan_capi_pvt.h"
32
#include "chan_capi_app.h"
35
static char *tdesc = "(CAPI*) ECT";
36
static char *app = "capiECT";
37
static char *synopsis = "transfer the call that is on hold";
44
static int capiECT_exec(struct ast_channel *chan, void *data)
46
struct ast_capi_pvt *i = chan->pvt->pvt;
47
MESSAGE_EXCHANGE_ERROR Info;
55
ast_log(LOG_WARNING, "ECT requires an argument (destination phone number)\n");
59
/* Do our thing here */
60
if (i->onholdPLCI <= 0) {
61
ast_log(LOG_WARNING, "no call on hold that could be transfered\n");
65
ast_log(LOG_NOTICE,"ECT to %s\n",(char *)data);
66
capi_call(chan,data,0);
68
while ((i->state != CAPI_STATE_BCONNECTED) && (i->onholdPLCI != 0)) {
73
if (i->state == CAPI_STATE_BCONNECTED) {
74
ast_log(LOG_NOTICE,"call was answered\n");
76
capi_detect_dtmf(chan,1);
78
// put the stuff to play announcement message here ---> <-----
79
res = ast_say_digit_str(chan,i->cid,ecodes,chan->language);
81
ast_log(LOG_NOTICE,"res = %d\n",res);
82
// user pressed #, hangup
83
// first the holded user
84
// ast_exec("capiRETRIEVE",chan);
86
DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
87
DISCONNECT_REQ_PLCI(&CMSG) = i->onholdPLCI;
89
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
90
ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->onholdPLCI);
92
ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->onholdPLCI);
95
// then the destination
97
DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
98
DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
100
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
101
ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
103
ast_log(LOG_NOTICE, "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
106
// wait for the B3 layer to go down
107
while (i->state != CAPI_STATE_CONNECTED) {
111
DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
112
DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
114
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
115
ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
117
ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
121
LOCAL_USER_REMOVE(u);
125
// now drop the bchannel
126
DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
127
DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
129
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
130
ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
132
ast_log(LOG_NOTICE, "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
135
// wait for the B3 layer to go down
136
while (i->state != CAPI_STATE_CONNECTED) {
142
// the caller onhold hungup or died away, drop the answered call
143
if (i->onholdPLCI == 0) {
144
DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
145
DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
147
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
148
ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
150
ast_log(LOG_NOTICE, "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
155
ast_log(LOG_NOTICE,"onholdPLCI = %d\n",i->onholdPLCI);
159
fac[1] = 0x06; // ECT (function)
161
fac[3] = 4; //len //sservice specific parameter , cstruct
162
fac[4] = (i->onholdPLCI << 8 ) >> 8;
163
fac[5] = i->onholdPLCI >> 8;
167
FACILITY_REQ_HEADER(&CMSG,ast_capi_ApplID,ast_capi_MessageNumber++,0);
168
FACILITY_REQ_CONTROLLER(&CMSG) = i->controller;
169
FACILITY_REQ_PLCI(&CMSG) = i->onholdPLCI;
170
FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 0x0003; // sservices
171
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (char *)&fac;
173
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
174
ast_log(LOG_ERROR,"Error sending FACILITY_REQ\n");
177
ast_log(LOG_NOTICE,"sent FACILITY_REQ PLCI = %#x (%#x %#x) onholdPLCI = %#x\n ",i->PLCI,fac[4],fac[5],i->onholdPLCI);
178
ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
181
// i->outgoing = -1; // incoming + outgoing, this is a magic channel :)
183
LOCAL_USER_REMOVE(u);
187
int unload_module(void)
189
STANDARD_HANGUP_LOCALUSERS;
190
return ast_unregister_application(app);
193
int load_module(void)
195
return ast_register_application(app, capiECT_exec,synopsis,tdesc);
198
char *description(void)
206
STANDARD_USECOUNT(res);
212
return ASTERISK_GPL_KEY;