Added layer1 hold feature. Requires new mISDN and mISDNuser package from git.
[lcr.git] / joinremote.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** join functions for remote application                                     **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13 //#define __u8 unsigned char
14 //#define __u16 unsigned short
15 //#define __u32 unsigned int
16
17
18 /*
19  * constructor for a new join 
20  * the join will have a relation to the calling endpoint
21  */
22 JoinRemote::JoinRemote(unsigned int serial, char *remote_name, int remote_id) : Join()
23 {
24         PDEBUG(DEBUG_JOIN, "Constructor(new join)");
25         union parameter param;
26
27         SCPY(j_remote_name, remote_name);
28         j_remote_id = remote_id;
29         j_type = JOIN_TYPE_REMOTE;
30
31         j_epoint_id = serial; /* this is the endpoint, if created by epoint */
32         if (j_epoint_id)
33                 PDEBUG(DEBUG_JOIN, "New remote join connected to endpoint id %lu and application %s\n", j_epoint_id, remote_name);
34
35         /* send new ref to remote socket */
36         memset(&param, 0, sizeof(union parameter));
37         if (serial)
38                 param.direction = 1; /* new ref from lcr */
39         /* the j_serial is assigned by Join() parent. this is sent as new ref */
40         if (admin_message_from_join(j_remote_id, j_serial, MESSAGE_NEWREF, &param)<0)
41                 FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", j_remote_name);
42 }
43
44
45 /*
46  * join descructor
47  */
48 JoinRemote::~JoinRemote()
49 {
50 }
51
52
53 /* join process is called from the main loop
54  * it processes the current calling state.
55  * returns 0 if join nothing was done
56  */
57 int JoinRemote::handler(void)
58 {
59         return(0);
60 }
61
62
63 void JoinRemote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param)
64 {
65         /* if endpoint has just been removed, but still a message in the que */
66         if (epoint_id != j_epoint_id)
67                 return;
68         
69         /* look for Remote's interface */
70         if (admin_message_from_join(j_remote_id, j_serial, message_type, param)<0)
71         {
72                 PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all joins.\n", j_remote_name);
73                 return;         
74         }
75
76         if (message_type == MESSAGE_RELEASE)
77         {
78                 delete this;
79                 return;
80         }
81 }
82
83 void JoinRemote::message_remote(int message_type, union parameter *param)
84 {
85         struct lcr_msg *message;
86
87         /* create relation if no relation exists */
88         if (!j_epoint_id)
89         {
90                 class Endpoint          *epoint;
91
92                 if (!(epoint = new Endpoint(0, j_serial)))
93                         FATAL("No memory for Endpoint instance\n");
94                 j_epoint_id = epoint->ep_serial;
95                 if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing
96                         FATAL("No memory for Endpoint Application instance\n");
97         }
98
99         /* set serial on bchannel message
100          * also ref is given, so we send message with ref */
101         if (message_type == MESSAGE_BCHANNEL)
102         {
103                 message_bchannel_from_remote(this, param->bchannel.type, param->bchannel.handle);
104                 return;
105         }
106         
107         /* cannot just forward, because param is not of container "struct lcr_msg" */
108         message = message_create(j_serial, j_epoint_id, JOIN_TO_EPOINT, message_type);
109         memcpy(&message->param, param, sizeof(message->param));
110         message_put(message);
111
112         if (message_type == MESSAGE_RELEASE)
113         {
114                 delete this;
115                 return;
116         }
117 }
118
119 void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type)
120 {
121         union parameter param;
122
123         memset(&param, 0, sizeof(union parameter));
124         param.bchannel.type = type;
125         param.bchannel.handle = handle;
126         param.bchannel.tx_gain = tx_gain;
127         param.bchannel.rx_gain = rx_gain;
128         if (pipeline)
129                 SCPY(param.bchannel.pipeline, pipeline);
130         if (crypt_len)
131                 memcpy(param.bchannel.crypt, crypt, crypt_len);
132         param.bchannel.crypt_type = crypt_type;
133         if (admin_message_from_join(remote_id, ref, MESSAGE_BCHANNEL, &param)<0)
134         {
135                 PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
136                 return;         
137         }
138 }
139
140
141