Fix: Allow recording of audio for SIP/remote/GSM interfaces too
[lcr.git] / remote.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** LCR                                                                       **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN remote                                                              **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 unsigned int new_remote = 1000;
15
16 /*
17  * constructor
18  */
19 Premote::Premote(int type, char *portname, struct port_settings *settings, struct interface *interface, int remote_id) : Port(type, portname, settings, interface)
20 {
21         union parameter param;
22
23         p_callerinfo.itype = (interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
24         p_r_ref = new_remote++;
25         SCPY(p_r_remote_app, interface->remote_app);
26         p_r_tones = (interface->is_tones == IS_YES);
27
28         /* send new ref to remote socket */
29         memset(&param, 0, sizeof(union parameter));
30         if (type == PORT_TYPE_REMOTE_OUT)
31                 param.newref.direction = 1; /* new ref from lcr */
32         p_r_remote_id = remote_id;
33         if (admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_NEWREF, &param) < 0)
34                 FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", p_r_remote_app);
35
36         PDEBUG(DEBUG_PORT, "Created new RemotePort(%s).\n", portname);
37
38 }
39
40 /*
41  * destructor
42  */
43 Premote::~Premote()
44 {
45         PDEBUG(DEBUG_PORT, "Destroyed Remote process(%s).\n", p_name);
46 }
47
48 /*
49  * endpoint sends messages to the port
50  */
51 int Premote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param)
52 {
53         struct epoint_list *epointlist;
54
55         if (Port::message_epoint(epoint_id, message_type, param))
56                 return 1;
57
58         switch (message_type) {
59         case MESSAGE_SETUP:
60                 struct interface *interface;
61                 interface = getinterfacebyname(p_interface_name);
62                 if (!interface) {
63                         PERROR("Cannot find interface %s.\n", p_interface_name);
64                         return 0;
65                 }
66                 /* attach only if not already */
67                 epointlist = p_epointlist;
68                 while(epointlist) {
69                         if (epointlist->epoint_id == epoint_id)
70                                 break;
71                         epointlist = epointlist->next;
72                 }
73                 if (!epointlist)
74                         epointlist_new(epoint_id);
75
76                 /* set context to pbx */
77                 if (!param->setup.dialinginfo.context[0]) {
78                         if (interface->remote_context[0])
79                                 SCPY(param->setup.dialinginfo.context, interface->remote_context);
80                         else
81                                 SCPY(param->setup.dialinginfo.context, "lcr");
82                 }
83                 memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
84                 memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
85                 memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
86                 memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
87                 /* screen */
88                 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_interface_name);
89                 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_interface_name);
90                 do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_interface_name);
91                 memcpy(&param->setup.callerinfo, &p_callerinfo, sizeof(p_callerinfo));
92                 memcpy(&param->setup.redirinfo, &p_redirinfo, sizeof(p_redirinfo));
93
94                 new_state(PORT_STATE_OUT_SETUP);
95                 break;
96
97         case MESSAGE_PROCEEDING:
98                 new_state(PORT_STATE_IN_PROCEEDING);
99                 break;
100
101         case MESSAGE_ALERTING:
102                 new_state(PORT_STATE_IN_ALERTING);
103                 break;
104
105         case MESSAGE_CONNECT:
106                 memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
107                 new_state(PORT_STATE_CONNECT);
108                 break;
109
110         case MESSAGE_DISCONNECT:
111                 new_state(PORT_STATE_OUT_DISCONNECT);
112                 break;
113
114         case MESSAGE_RELEASE:
115                 new_state(PORT_STATE_RELEASE);
116                 break;
117         }
118
119         /* look for Remote's interface */
120         if (admin_message_from_lcr(p_r_remote_id, p_r_ref, message_type, param)<0) {
121                 PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_r_remote_app);
122                 return 0;               
123         }
124
125         if (message_type == MESSAGE_RELEASE) {
126                 new_state(PORT_STATE_RELEASE);
127                 delete this;
128                 return 0;
129         }
130
131         return 0;
132 }
133
134 void Premote::message_remote(int message_type, union parameter *param)
135 {
136         class Endpoint *epoint;
137         struct lcr_msg *message;
138         struct interface *interface;
139
140         switch (message_type) {
141         case MESSAGE_TRAFFIC:
142                 /* record audio */
143                 if (p_record)
144                         record(param->traffic.data, param->traffic.len, 0); // from down
145                 if (p_tap)
146                         tap(param->traffic.data, param->traffic.len, 0); // from down
147                 bridge_tx(param->traffic.data, param->traffic.len);
148                 if (p_tone_name[0]) {
149                         read_audio(param->traffic.data, param->traffic.len);
150                         /* record audio */
151                         if (p_record)
152                                 record(param->traffic.data, param->traffic.len, 1); // from up
153                         if (p_tap)
154                                 tap(param->traffic.data, param->traffic.len, 1); // from up
155                         admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, param);
156                 }
157                 return;
158
159         case MESSAGE_SETUP:
160                 interface = getinterfacebyname(p_interface_name);
161                 if (!interface) {
162                         PERROR("Cannot find interface %s.\n", p_interface_name);
163                         return;
164                 }
165
166                 /* enable audio path */
167                 if (interface->is_tones == IS_YES) {
168                         union parameter newparam;
169                         memset(&newparam, 0, sizeof(union parameter));
170                         admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_PATTERN, &newparam);
171                         newparam.audiopath = 1;
172                         admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_AUDIOPATH, &newparam);
173                 }
174
175                 /* set source interface */
176                 param->setup.callerinfo.itype = p_callerinfo.itype;
177                 SCPY(param->setup.callerinfo.interface, interface->name);
178                 
179                 /* create endpoint */
180                 if (p_epointlist)
181                         FATAL("Incoming call but already got an endpoint.\n");
182                 if (!(epoint = new Endpoint(p_serial, 0)))
183                         FATAL("No memory for Endpoint instance\n");
184                 epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming
185
186                 epointlist_new(epoint->ep_serial);
187
188                 memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
189                 memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
190                 memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
191                 memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
192
193                 new_state(PORT_STATE_IN_SETUP);
194                 break;
195
196         case MESSAGE_PROCEEDING:
197                 new_state(PORT_STATE_OUT_PROCEEDING);
198                 break;
199
200         case MESSAGE_ALERTING:
201                 new_state(PORT_STATE_OUT_ALERTING);
202                 break;
203
204         case MESSAGE_CONNECT:
205                 memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
206                 new_state(PORT_STATE_CONNECT);
207                 break;
208
209         case MESSAGE_DISCONNECT:
210                 new_state(PORT_STATE_IN_DISCONNECT);
211                 break;
212
213         case MESSAGE_RELEASE:
214                 new_state(PORT_STATE_RELEASE);
215                 break;
216         }
217
218         /* cannot just forward, because param is not of container "struct lcr_msg" */
219         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
220         memcpy(&message->param, param, sizeof(message->param));
221         message_put(message);
222
223         if (message_type == MESSAGE_RELEASE) {
224                 new_state(PORT_STATE_RELEASE);
225                 delete this;
226                 return;
227         }
228 }
229
230 /* receive from remote Port instance */
231 int Premote::bridge_rx(unsigned char *data, int len)
232 {
233         union parameter newparam;
234         int l;
235
236         /* don't send tones, if not enabled or not connected */
237         if (!p_r_tones
238          && p_state != PORT_STATE_CONNECT)
239                 return 0;
240
241         if (p_tone_name[0])
242                 return 0;
243
244         memset(&newparam, 0, sizeof(union parameter));
245         /* split, if exeeds data size */
246         while(len) {
247                 l = (len > (int)sizeof(newparam.traffic.data)) ? sizeof(newparam.traffic.data) : len;
248                 newparam.traffic.len = l;
249                 len -= l;
250                 memcpy(newparam.traffic.data, data, l);
251                 data += l;
252                 /* record audio */
253                 if (p_record)
254                         record(data, len, 1); // from up
255                 if (p_tap)
256                         tap(data, len, 1); // from up
257                 admin_message_from_lcr(p_r_remote_id, p_r_ref, MESSAGE_TRAFFIC, &newparam);
258         }
259
260         return 0;
261 }
262
263