1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
14 unsigned int new_remote = 1000;
19 Premote::Premote(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode, int remote_id) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
21 union parameter param;
23 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
24 p_m_r_ref = new_remote++;
25 SCPY(p_m_r_remote_app, mISDNport->ifport->remote_app);
28 /* send new ref to remote socket */
29 memset(¶m, 0, sizeof(union parameter));
30 if (type == PORT_TYPE_REMOTE_OUT)
31 param.newref.direction = 1; /* new ref from lcr */
32 p_m_r_remote_id = remote_id;
33 if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_NEWREF, ¶m) < 0)
34 FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", mISDNport->ifport->remote_app);
36 PDEBUG(DEBUG_GSM, "Created new RemotePort(%s).\n", portname);
45 /* need to remote (import) external channel from remote application */
47 message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, p_m_r_handle, 0, 0, 0, 0, 0, 0, 1);
48 chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
49 add_trace("type", NULL, "remove");
50 add_trace("channel", NULL, "%d.%d", p_m_r_handle>>8, p_m_r_handle&0xff);
54 PDEBUG(DEBUG_GSM, "Destroyed Remote process(%s).\n", p_name);
59 * endpoint sends messages to the port
61 int Premote::message_epoint(unsigned int epoint_id, int message_type, union parameter *param)
63 struct lcr_msg *message;
66 struct epoint_list *epointlist;
68 if (PmISDN::message_epoint(epoint_id, message_type, param))
71 if (message_type == MESSAGE_SETUP) {
72 ret = channel = hunt_bchannel();
76 ret = seize_bchannel(channel, 1);
79 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
80 message->param.disconnectinfo.cause = 34;
81 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
83 new_state(PORT_STATE_RELEASE);
87 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
89 /* attach only if not already */
90 epointlist = p_epointlist;
92 if (epointlist->epoint_id == epoint_id)
94 epointlist = epointlist->next;
97 epointlist_new(epoint_id);
99 /* set context to pbx */
100 SCPY(param->setup.context, "pbx");
103 /* look for Remote's interface */
104 if (admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, message_type, param)<0) {
105 PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all remote ports.\n", p_m_mISDNport->ifport->remote_app);
109 /* enable audio path */
110 if (message_type == MESSAGE_SETUP) {
111 union parameter newparam;
112 memset(&newparam, 0, sizeof(union parameter));
113 admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam);
114 newparam.audiopath = 1;
115 admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam);
118 if (message_type == MESSAGE_RELEASE) {
119 new_state(PORT_STATE_RELEASE);
127 void Premote::message_remote(int message_type, union parameter *param)
129 class Endpoint *epoint;
130 struct lcr_msg *message;
134 if (message_type == MESSAGE_SETUP) {
135 /* enable audio path */
136 union parameter newparam;
137 memset(&newparam, 0, sizeof(union parameter));
138 admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_PATTERN, &newparam);
139 newparam.audiopath = 1;
140 admin_message_from_lcr(p_m_r_remote_id, p_m_r_ref, MESSAGE_AUDIOPATH, &newparam);
142 /* set source interface */
143 param->setup.callerinfo.itype = p_callerinfo.itype;
144 param->setup.callerinfo.isdn_port = p_m_portnum;
145 SCPY(param->setup.callerinfo.interface, p_m_mISDNport->ifport->interface->name);
147 ret = channel = hunt_bchannel();
152 ret = seize_bchannel(channel, 1);
155 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
156 message->param.disconnectinfo.cause = 34;
157 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
158 message_put(message);
159 new_state(PORT_STATE_RELEASE);
163 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
165 /* create endpoint */
167 FATAL("Incoming call but already got an endpoint.\n");
168 if (!(epoint = new Endpoint(p_serial, 0)))
169 FATAL("No memory for Endpoint instance\n");
170 epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
172 epointlist_new(epoint->ep_serial);
175 /* set serial on bchannel message
176 * also ref is given, so we send message with ref */
177 if (message_type == MESSAGE_BCHANNEL) {
179 unsigned int portid = (mISDNloop.port<<8) + i+1+(i>=15);
180 switch (param->bchannel.type) {
181 case BCHANNEL_REQUEST:
182 p_m_r_handle = portid;
183 message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_ASSIGN, portid, 0, 0, 0, 0, 0, 0, 1);
184 chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
185 add_trace("type", NULL, "assign");
186 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
189 case BCHANNEL_RELEASE:
191 message_bchannel_to_remote(p_m_r_remote_id, p_m_r_ref, BCHANNEL_REMOVE, portid, 0, 0, 0, 0, 0, 0, 1);
192 chan_trace_header(p_m_mISDNport, this, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
193 add_trace("type", NULL, "remove");
194 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
201 /* cannot just forward, because param is not of container "struct lcr_msg" */
202 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, message_type);
203 memcpy(&message->param, param, sizeof(message->param));
204 message_put(message);
206 if (message_type == MESSAGE_RELEASE) {
207 new_state(PORT_STATE_RELEASE);
213 /* select free bchannel from loopback interface */
214 int Premote::hunt_bchannel(void)
216 return loop_hunt_bchannel(this, p_m_mISDNport);