+/* process bchannel export/import message from join */
+void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr)
+{
+ class Endpoint *epoint;
+ class Port *port;
+ class PmISDN *isdnport;
+ struct mISDNport *mISDNport;
+ int i, ii;
+
+ switch(type)
+ {
+ case BCHANNEL_REQUEST:
+ /* find the port object for the join object ref */
+ if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
+ return;
+ }
+ if (!epoint->ep_portlist)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
+ return;
+ }
+ if (epoint->ep_portlist->next)
+ {
+ PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial);
+ }
+ if (!(port = find_port_id(epoint->ep_portlist->port_id)))
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
+ return;
+ }
+ if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
+ {
+ PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
+ }
+ isdnport = (class PmISDN *)port;
+
+ /* assign */
+ if (isdnport->p_m_exportremote)
+ {
+ PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
+ break;
+ }
+ chan_trace_header(isdnport->p_m_mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "export request");
+ isdnport->p_m_exportremote = joinremote->j_serial;
+ if (isdnport->p_m_mISDNport && isdnport->p_m_b_index>=0)
+ bchannel_event(isdnport->p_m_mISDNport, isdnport->p_m_b_index, B_EVENT_EXPORTREQUEST, joinremote->j_serial);
+ end_trace();
+ break;
+
+ case BCHANNEL_ASSIGN_ACK:
+ case BCHANNEL_REMOVE_ACK:
+ /* find mISDNport for stack ID */
+ mISDNport = mISDNport_first;
+ while(mISDNport)
+ {
+ i = 0;
+ ii = mISDNport->b_num;
+ while(i < ii)
+ {
+ if (mISDNport->b_addr[i] == addr)
+ break;
+ i++;
+ }
+ if (i != ii)
+ break;
+ mISDNport = mISDNport->next;
+ }
+ /* mISDNport may now be set or NULL */
+
+ /* set */
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
+ if (mISDNport && i>=0)
+ bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED, 0);
+ end_trace();
+ break;
+ default:
+ PERROR("received wrong bchannel message type %d from remote\n", type);
+ }
+}
+