1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
25 #include <mISDNuser/net_l2.h>
35 Pdss1::Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : PmISDN(type, mISDNport, portname, settings, channel, exclusive)
37 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
38 p_m_d_ntmode = mISDNport->ntmode;
42 p_m_d_notify_pending = NULL;
43 p_m_d_collect_cause = 0;
44 p_m_d_collect_location = 0;
46 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, %s port #%d\n", portname, mISDNport->use, (mISDNport->ntmode)?"NT":"TE", p_m_portnum);
55 /* remove queued message */
57 message_free(p_m_d_queue);
59 if (p_m_d_notify_pending)
60 message_free(p_m_d_notify_pending);
62 /* check how many processes are left */
63 if (p_m_d_ntmode == 1)
65 if (p_m_mISDNport->nst.layer3->proc)
66 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). WARNING: There is still a layer 3 process left. Ignore this, if currently are other calls. This message is not an error!\n", p_name);
72 * create layer 3 message
75 static struct l3_msg *create_l3msg(void)
77 static msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
92 size = sizeof(Q931_info_t)+2;
96 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
103 dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
106 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
107 frm = (iframe_t *)dmsg->data;
110 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
117 FATAL("Cannot allocate memory, system overloaded.\n");
118 exit(0); // make gcc happy
122 msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
126 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
130 FATAL("Cannot allocate memory, system overloaded.\n");
131 exit(0); // make gcc happy
136 * if we received a first reply to the setup message,
137 * we will check if we have now channel information
138 * return: <0: error, call is released, -cause is given
139 * 0: ok, nothing to do
141 int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int exclusive)
147 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
148 RELEASE_COMPLETE_t *release_complete;
152 /* correct exclusive to 0, if no explicit channel was given */
153 if (exclusive<0 || channel<=0)
156 /* select scenario */
157 if (p_m_b_channel && p_m_b_exclusive)
159 /*** we gave an exclusive channel (or if we are done) ***/
161 /* if not first reply, we are done */
162 if (p_state != PORT_STATE_OUT_SETUP)
165 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
166 add_trace("channel", "request", "%d (forced)", p_m_b_channel);
167 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
169 /* if give channel not accepted or not equal */
170 if (channel!=-1 && p_m_b_channel!=channel)
172 add_trace("conclusion", NULL, "forced channel not accepted");
178 add_trace("conclusion", NULL, "channel was accepted");
179 add_trace("connect", "channel", "%d", p_m_b_channel);
182 /* activate our exclusive channel */
183 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
187 /*** we gave a non-exclusive channel ***/
189 /* if not first reply, we are done */
190 if (p_state != PORT_STATE_OUT_SETUP)
193 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
194 add_trace("channel", "request", "%d (suggest)", p_m_b_channel);
195 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
197 /* if channel was accepted as given */
198 if (channel==-1 || p_m_b_channel==channel)
200 add_trace("conclusion", NULL, "channel was accepted as given");
201 add_trace("connect", "channel", "%d", p_m_b_channel);
203 p_m_b_exclusive = 1; // we are done
204 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
208 /* if channel value is faulty */
211 add_trace("conclusion", NULL, "illegal reply");
213 ret = -111; // protocol error
217 /* if channel was not accepted, try to get it */
218 ret = seize_bchannel(channel, 1); // exclusively
219 add_trace("channel", "available", ret<0?"no":"yes");
222 add_trace("conclusion", NULL, "replied channel not available");
226 add_trace("conclusion", NULL, "replied channel accepted");
227 add_trace("connect", "channel", "%d", p_m_b_channel);
230 /* activate channel given by remote */
231 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
235 /*** we sent 'any channel acceptable' ***/
237 /* if not first reply, we are done */
238 if (p_state != PORT_STATE_OUT_SETUP)
241 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
242 add_trace("channel", "request", "any");
243 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
244 /* if no channel was replied */
247 add_trace("conclusion", NULL, "no channel, protocol error");
249 ret = -111; // protocol error
253 /* we will see, if our received channel is available */
254 ret = seize_bchannel(channel, 1); // exclusively
255 add_trace("channel", "available", ret<0?"no":"yes");
258 add_trace("conclusion", NULL, "replied channel not available");
262 add_trace("conclusion", NULL, "replied channel accepted");
263 add_trace("connect", "channel", "%d", p_m_b_channel);
266 /* activate channel given by remote */
267 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
270 /*** we sent 'no channel available' ***/
272 /* if not the first reply, but a connect, we are forced */
273 if (prim==(CC_CONNECT | INDICATION) && p_state!=PORT_STATE_OUT_SETUP)
275 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (connect)", DIRECTION_NONE);
276 add_trace("channel", "request", "no-channel");
277 add_trace("channel", "reply", (channel>=0)?"%d%s":"(none)", channel, exclusive?" (forced)":"");
280 goto use_from_connect;
282 ret = seize_bchannel(CHANNEL_ANY, 0); // any channel
283 add_trace("channel", "available", ret<0?"no":"yes");
286 add_trace("conclusion", NULL, "no channel available during call-waiting");
290 add_trace("conclusion", NULL, "using channel %d", p_m_b_channel);
291 add_trace("connect", "channel", "%d", p_m_b_channel);
293 p_m_b_exclusive = 1; // we are done
295 /* activate channel given by remote */
296 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
300 /* if not first reply, we are done */
301 if (p_state != PORT_STATE_OUT_SETUP)
304 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
305 add_trace("channel", "request", "no-channel");
306 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
307 /* if first reply has no channel, we are done */
310 add_trace("conclusion", NULL, "no channel until connect");
315 /* we will see, if our received channel is available */
317 ret = seize_bchannel(channel, exclusive);
318 add_trace("channel", "available", ret<0?"no":"yes");
321 add_trace("conclusion", NULL, "replied channel not available");
325 add_trace("conclusion", NULL, "replied channel accepted");
326 add_trace("connect", "channel", "%d", p_m_b_channel);
328 p_m_b_exclusive = 1; // we are done
330 /* activate channel given by remote */
331 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
337 * NOTE: we send MT_RELEASE_COMPLETE to "REJECT" the channel
338 * in response to the setup reply
341 l3m = create_l3msg();
343 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
344 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
346 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
348 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
350 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
354 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
356 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
358 new_state(PORT_STATE_RELEASE);
360 return(-34); /* to epoint: no channel available */
365 * hunt bchannel for incoming setup or retrieve or resume
367 int Pdss1::hunt_bchannel(int channel, int exclusive)
369 struct select_channel *selchannel;
370 struct interface_port *ifport = p_m_mISDNport->ifport;
373 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (setup)", DIRECTION_NONE);
376 if (channel == CHANNEL_NO)
377 add_trace("channel", "request", "no-channel");
379 add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":"");
380 if (channel==CHANNEL_NO && p_type==PORT_TYPE_DSS1_TE_IN)
382 add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode");
384 return(-6); // channel unacceptable
386 if (channel <= 0) /* not given, no channel, whatever.. */
387 channel = CHANNEL_ANY; /* any channel */
388 add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved);
389 if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) // of out chan..
391 add_trace("conclusion", NULL, "all channels are reserved");
393 return(-34); // no channel
395 if (channel == CHANNEL_ANY)
399 /* check for given channel in selection list */
400 selchannel = ifport->in_channel;
403 if (selchannel->channel == channel || selchannel->channel == CHANNEL_FREE)
405 selchannel = selchannel->next;
410 /* exclusive channel requests must be in the list */
415 add_trace("conclusion", NULL, "exclusively requested channel not in list");
417 return(-6); // channel unacceptable
419 i = selchannel->channel-1-(selchannel->channel>=17);
420 if (p_m_mISDNport->b_port[i] == NULL)
422 add_trace("conclusion", NULL, "exclusively requested channel is busy");
424 return(-6); // channel unacceptable
427 /* requested channels in list will be used */
430 i = selchannel->channel-1-(selchannel->channel>=17);
431 if (p_m_mISDNport->b_port[i] == NULL)
435 /* if channel is not available or not in list, it must be searched */
437 /* check for first free channel in list */
439 selchannel = ifport->in_channel;
442 switch(selchannel->channel)
444 case CHANNEL_FREE: /* free channel */
445 add_trace("hunting", "channel", "free");
446 if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num)
447 break; /* all channel in use or reserverd */
450 while(i < p_m_mISDNport->b_num)
452 if (p_m_mISDNport->b_port[i] == NULL)
454 channel = i+1+(i>=15);
462 add_trace("hunting", "channel", "%d", selchannel->channel);
463 if (selchannel->channel<1 || selchannel->channel==16)
464 break; /* invalid channels */
465 i = selchannel->channel-1-(selchannel->channel>=17);
466 if (i >= p_m_mISDNport->b_num)
467 break; /* channel not in port */
468 if (p_m_mISDNport->b_port[i] == NULL)
470 channel = selchannel->channel;
476 break; /* found channel */
477 selchannel = selchannel->next;
481 add_trace("conclusion", NULL, "no channel available");
483 return(-6); // channel unacceptable
487 add_trace("conclusion", NULL, "channel available");
488 add_trace("connect", "channel", "%d", channel);
494 * handles all indications
496 /* CC_SETUP INDICATION */
498 void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
501 void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
503 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
505 SETUP_t *setup = (SETUP_t *)((unsigned long)data + headerlen);
507 int calling_type, calling_plan, calling_present, calling_screen;
508 int called_type, called_plan;
509 int redir_type, redir_plan, redir_present, redir_screen, redir_reason;
510 int hlc_coding, hlc_presentation, hlc_interpretation, hlc_hlc, hlc_exthlc;
511 int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user;
512 int exclusive, channel;
514 unsigned char keypad[32] = "";
515 unsigned char useruser[128];
516 int useruser_len = 0, useruser_protocol;
517 class Endpoint *epoint;
518 struct message *message;
521 /* callref from nt-lib */
524 /* nt-library now gives us the id via CC_SETUP */
525 if (dinfo&(~0xff) == 0xff00)
526 FATAL("l3-stack gives us a process id 0xff00-0xffff\n");
527 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_CR_IND, DIRECTION_IN);
529 add_trace("callref", "old", "0x%x", p_m_d_l3id);
530 add_trace("callref", "new", "0x%x", dinfo);
532 if (p_m_d_l3id&(~0xff) == 0xff00)
533 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
535 p_m_d_ces = setup->ces;
539 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_IND, DIRECTION_IN);
541 dec_ie_calling_pn(l3m, &calling_type, &calling_plan, &calling_present, &calling_screen, (unsigned char *)p_callerinfo.id, sizeof(p_callerinfo.id));
542 dec_ie_called_pn(l3m, &called_type, &called_plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
543 dec_ie_keypad(l3m, (unsigned char *)keypad, sizeof(keypad));
544 /* te-mode: CNIP (calling name identification presentation) */
546 dec_facility_centrex(l3m, (unsigned char *)p_callerinfo.name, sizeof(p_callerinfo.name));
547 dec_ie_useruser(l3m, &useruser_protocol, useruser, &useruser_len);
548 dec_ie_complete(l3m, &p_dialinginfo.sending_complete);
549 dec_ie_redir_nr(l3m, &redir_type, &redir_plan, &redir_present, &redir_screen, &redir_reason, (unsigned char *)p_redirinfo.id, sizeof(p_redirinfo.id));
550 dec_ie_channel_id(l3m, &exclusive, &channel);
551 dec_ie_hlc(l3m, &hlc_coding, &hlc_interpretation, &hlc_presentation, &hlc_hlc, &hlc_exthlc);
552 dec_ie_bearer(l3m, &bearer_coding, &bearer_capability, &bearer_mode, &bearer_rate, &bearer_multi, &bearer_user);
554 dec_ie_calling_pn(setup->CALLING_PN, (Q931_info_t *)((unsigned long)data+headerlen), &calling_type, &calling_plan, &calling_present, &calling_screen, (unsigned char *)p_callerinfo.id, sizeof(p_callerinfo.id));
555 dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &called_type, &called_plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
556 dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
557 /* te-mode: CNIP (calling name identification presentation) */
559 dec_facility_centrex(setup->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)p_callerinfo.name, sizeof(p_callerinfo.name));
560 dec_ie_useruser(setup->USER_USER, (Q931_info_t *)((unsigned long)data+headerlen), &useruser_protocol, useruser, &useruser_len);
561 dec_ie_complete(setup->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete);
562 dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *)((unsigned long)data+headerlen), &redir_type, &redir_plan, &redir_present, &redir_screen, &redir_reason, (unsigned char *)p_redirinfo.id, sizeof(p_redirinfo.id));
563 dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
564 dec_ie_hlc(setup->HLC, (Q931_info_t *)((unsigned long)data+headerlen), &hlc_coding, &hlc_interpretation, &hlc_presentation, &hlc_hlc, &hlc_exthlc);
565 dec_ie_bearer(setup->BEARER, (Q931_info_t *)((unsigned long)data+headerlen), &bearer_coding, &bearer_capability, &bearer_mode, &bearer_rate, &bearer_multi, &bearer_user);
569 /* if blocked, release call with MT_RELEASE_COMPLETE */
570 if (p_m_mISDNport->ifport->block)
572 RELEASE_COMPLETE_t *release_complete;
575 l3m = create_l3msg();
577 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
578 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
580 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
582 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 27); /* temporary unavailable */
584 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 27); /* temporary unavailable */
586 add_trace("reason", NULL, "port blocked");
589 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
591 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
593 new_state(PORT_STATE_RELEASE);
599 switch (calling_present)
602 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
605 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
608 p_callerinfo.present = INFO_PRESENT_ALLOWED;
611 switch (calling_screen)
614 p_callerinfo.screen = INFO_SCREEN_USER;
617 p_callerinfo.screen = INFO_SCREEN_NETWORK;
620 switch (calling_type)
623 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
624 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
625 p_callerinfo.screen = INFO_SCREEN_NETWORK;
628 p_callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
631 p_callerinfo.ntype = INFO_NTYPE_NATIONAL;
634 p_callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
637 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
640 p_callerinfo.isdn_port = p_m_portnum;
641 SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
643 /* dialing information */
644 SCAT(p_dialinginfo.id, (char *)keypad);
648 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
651 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
654 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
657 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
662 switch (redir_present)
665 p_redirinfo.present = INFO_PRESENT_RESTRICTED;
668 p_redirinfo.present = INFO_PRESENT_NOTAVAIL;
671 p_redirinfo.present = INFO_PRESENT_ALLOWED;
674 switch (redir_screen)
677 p_redirinfo.screen = INFO_SCREEN_USER;
680 p_redirinfo.screen = INFO_SCREEN_NETWORK;
683 switch (redir_reason)
686 p_redirinfo.reason = INFO_REDIR_BUSY;
689 p_redirinfo.reason = INFO_REDIR_NORESPONSE;
692 p_redirinfo.reason = INFO_REDIR_UNCONDITIONAL;
695 p_redirinfo.reason = INFO_REDIR_CALLDEFLECT;
698 p_redirinfo.reason = INFO_REDIR_OUTOFORDER;
701 p_redirinfo.reason = INFO_REDIR_UNKNOWN;
707 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
708 p_redirinfo.present = INFO_PRESENT_NULL; /* not redirecting */
709 p_redirinfo.reason = INFO_REDIR_UNKNOWN;
712 p_redirinfo.ntype = INFO_NTYPE_INTERNATIONAL;
715 p_redirinfo.ntype = INFO_NTYPE_NATIONAL;
718 p_redirinfo.ntype = INFO_NTYPE_SUBSCRIBER;
721 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
724 p_redirinfo.isdn_port = p_m_portnum;
726 /* bearer capability */
727 switch (bearer_capability)
730 p_capainfo.bearer_capa = INFO_BC_AUDIO;
731 bearer_user = (options.law=='a')?3:2;
734 p_capainfo.bearer_capa = bearer_capability;
740 p_capainfo.bearer_mode = INFO_BMODE_PACKET;
743 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
749 p_capainfo.bearer_info1 = INFO_INFO1_NONE;
752 p_capainfo.bearer_info1 = bearer_user + 0x80;
760 p_capainfo.hlc = INFO_HLC_NONE;
763 p_capainfo.hlc = hlc_hlc + 0x80;
769 p_capainfo.exthlc = INFO_HLC_NONE;
772 p_capainfo.exthlc = hlc_exthlc + 0x80;
777 ret = channel = hunt_bchannel(channel, exclusive);
782 ret = seize_bchannel(channel, 1);
787 * NOTE: we send MT_RELEASE_COMPLETE to "REJECT" the channel
788 * in response to the setup
791 l3m = create_l3msg();
793 RELEASE_COMPLETE_t *release_complete;
794 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
795 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
797 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
799 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
801 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
805 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
807 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
809 new_state(PORT_STATE_RELEASE);
813 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
815 /* create endpoint */
817 FATAL("Incoming call but already got an endpoint.\n");
818 if (!(epoint = new Endpoint(p_serial, 0)))
819 FATAL("No memory for Endpoint instance\n");
820 if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
821 FATAL("No memory for Endpoint Application instance\n");
822 epointlist_new(epoint->ep_serial);
824 /* send setup message to endpoit */
825 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
826 message->param.setup.isdn_port = p_m_portnum;
827 message->param.setup.port_type = p_type;
828 message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
829 memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
830 memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
831 memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
832 memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
833 memcpy(message->param.setup.useruser.data, &useruser, useruser_len);
834 message->param.setup.useruser.len = useruser_len;
835 message->param.setup.useruser.protocol = useruser_protocol;
836 message_put(message);
838 new_state(PORT_STATE_IN_SETUP);
841 /* CC_INFORMATION INDICATION */
843 void Pdss1::information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
846 void Pdss1::information_ind(unsigned long prim, unsigned long dinfo, void *data)
848 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
849 INFORMATION_t *information = (INFORMATION_t *)((unsigned long)data + headerlen);
852 unsigned char keypad[32] = "";
853 struct message *message;
855 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_IND, DIRECTION_IN);
857 dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
858 dec_ie_keypad(information->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
859 dec_ie_complete(information->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete);
861 dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
862 dec_ie_keypad(information->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
863 dec_ie_complete(information->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete);
867 SCAT(p_dialinginfo.id, (char *)keypad);
871 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
874 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
877 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
880 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
883 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
884 memcpy(&message->param.information, &p_dialinginfo, sizeof(struct dialing_info));
885 message_put(message);
886 /* reset overlap timeout */
890 /* CC_SETUP_ACCNOWLEDGE INDICATION */
892 void Pdss1::setup_acknowledge_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
895 void Pdss1::setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void *data)
897 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
898 SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *)((unsigned long)data + headerlen);
900 int exclusive, channel;
901 int coding, location, progress;
903 struct message *message;
905 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_IND, DIRECTION_IN);
907 dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
908 dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
910 dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
911 dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
915 /* process channel */
916 ret = received_first_reply_to_setup(prim, channel, exclusive);
919 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
920 message->param.disconnectinfo.cause = -ret;
921 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
922 message_put(message);
923 new_state(PORT_STATE_RELEASE);
928 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_OVERLAP);
929 message_put(message);
931 new_state(PORT_STATE_OUT_OVERLAP);
934 /* CC_PROCEEDING INDICATION */
936 void Pdss1::proceeding_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
939 void Pdss1::proceeding_ind(unsigned long prim, unsigned long dinfo, void *data)
941 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
942 CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *)((unsigned long)data + headerlen);
944 int exclusive, channel;
945 int coding, location, progress;
947 struct message *message;
948 int notify = -1, type, plan, present;
951 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_IND, DIRECTION_IN);
953 dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
954 dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
955 dec_ie_notify(NULL/*proceeding->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
956 dec_ie_redir_dn(proceeding->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
958 dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
959 dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
960 dec_ie_notify(NULL/*proceeding->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
961 dec_ie_redir_dn(proceeding->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
965 ret = received_first_reply_to_setup(prim, channel, exclusive);
968 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
969 message->param.disconnectinfo.cause = -ret;
970 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
971 message_put(message);
972 new_state(PORT_STATE_RELEASE);
976 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
977 message_put(message);
979 new_state(PORT_STATE_OUT_PROCEEDING);
985 if (type >= 0 || notify)
987 if (!notify && type >= 0)
989 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
990 message->param.notifyinfo.notify = notify;
991 SCPY(message->param.notifyinfo.id, redir);
992 /* redirection number */
996 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
999 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1002 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1008 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1009 message->param.notifyinfo.present = INFO_PRESENT_NULL;
1012 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1015 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1018 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1021 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1024 message->param.notifyinfo.isdn_port = p_m_portnum;
1025 message_put(message);
1029 /* CC_ALERTING INDICATION */
1031 void Pdss1::alerting_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1034 void Pdss1::alerting_ind(unsigned long prim, unsigned long dinfo, void *data)
1036 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1037 ALERTING_t *alerting = (ALERTING_t *)((unsigned long)data + headerlen);
1039 int exclusive, channel;
1040 int coding, location, progress;
1042 struct message *message;
1043 int notify = -1, type, plan, present;
1046 l1l2l3_trace_header(p_m_mISDNport, this, L3_ALERTING_IND, DIRECTION_IN);
1048 dec_ie_channel_id(alerting->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1049 dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
1050 dec_ie_notify(NULL/*alerting->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
1051 dec_ie_redir_dn(alerting->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
1053 dec_ie_channel_id(alerting->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1054 dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
1055 dec_ie_notify(NULL/*alerting->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
1056 dec_ie_redir_dn(alerting->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
1060 /* process channel */
1061 ret = received_first_reply_to_setup(prim, channel, exclusive);
1064 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1065 message->param.disconnectinfo.cause = -ret;
1066 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1067 message_put(message);
1068 new_state(PORT_STATE_RELEASE);
1072 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
1073 message_put(message);
1075 new_state(PORT_STATE_OUT_ALERTING);
1081 if (type >= 0 || notify)
1083 if (!notify && type >= 0)
1085 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1086 message->param.notifyinfo.notify = notify;
1087 SCPY(message->param.notifyinfo.id, redir);
1091 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1094 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1097 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1103 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1104 message->param.notifyinfo.present = INFO_PRESENT_NULL;
1107 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1110 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1113 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1116 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1119 message->param.notifyinfo.isdn_port = p_m_portnum;
1120 message_put(message);
1124 /* CC_CONNECT INDICATION */
1126 void Pdss1::connect_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1129 void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data)
1131 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1133 CONNECT_t *connect = (CONNECT_t *)((unsigned long)data + headerlen);
1134 CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
1136 int exclusive, channel;
1137 int type, plan, present, screen;
1139 struct message *message;
1140 int bchannel_before;
1143 p_m_d_ces = connect->ces;
1145 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_IND, DIRECTION_IN);
1147 dec_ie_channel_id(connect->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1148 dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, &screen, (unsigned char *)p_connectinfo.id, sizeof(p_connectinfo.id));
1150 dec_ie_channel_id(connect->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1151 dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, &screen, (unsigned char *)p_connectinfo.id, sizeof(p_connectinfo.id));
1153 /* te-mode: CONP (connected name identification presentation) */
1155 dec_facility_centrex(connect->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)p_connectinfo.name, sizeof(p_connectinfo.name));
1158 /* select channel */
1159 bchannel_before = p_m_b_channel;
1160 ret = received_first_reply_to_setup(prim, channel, exclusive);
1163 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1164 message->param.disconnectinfo.cause = -ret;
1165 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1166 message_put(message);
1167 new_state(PORT_STATE_RELEASE);
1172 /* connect information */
1176 p_connectinfo.present = INFO_PRESENT_RESTRICTED;
1179 p_connectinfo.present = INFO_PRESENT_NOTAVAIL;
1182 p_connectinfo.present = INFO_PRESENT_ALLOWED;
1188 p_connectinfo.screen = INFO_SCREEN_USER;
1191 p_connectinfo.screen = INFO_SCREEN_NETWORK;
1197 p_connectinfo.present = INFO_PRESENT_NULL; /* no COLP info */
1198 p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1201 p_connectinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1204 p_connectinfo.ntype = INFO_NTYPE_NATIONAL;
1207 p_connectinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1210 p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1213 p_connectinfo.isdn_port = p_m_portnum;
1214 SCPY(p_connectinfo.interface, p_m_mISDNport->ifport->interface->name);
1216 /* only in nt-mode we send connect ack. in te-mode it is done by stack itself or optional */
1219 /* send connect acknowledge */
1221 l3m = create_l3msg();
1223 dmsg = create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT, dinfo, sizeof(CONNECT_ACKNOWLEDGE_t), p_m_d_ntmode);
1224 connect_acknowledge = (CONNECT_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1226 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_RES, DIRECTION_OUT);
1227 /* if we had no bchannel before, we send it now */
1228 if (!bchannel_before && p_m_b_channel)
1230 enc_ie_channel_id(l3m, 1, p_m_b_channel);
1232 enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
1236 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_CONNECT, l3m);
1238 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1242 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1243 memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
1244 message_put(message);
1246 new_state(PORT_STATE_CONNECT);
1249 /* CC_DISCONNECT INDICATION */
1251 void Pdss1::disconnect_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1254 void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data)
1256 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1257 DISCONNECT_t *disconnect = (DISCONNECT_t *)((unsigned long)data + headerlen);
1259 int location, cause;
1260 int coding, proglocation, progress;
1261 struct message *message;
1263 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_IND, DIRECTION_IN);
1265 dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &proglocation, &progress);
1266 dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1268 dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &proglocation, &progress);
1269 dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1272 if (location == LOCATION_PRIVATE_LOCAL)
1273 location = LOCATION_PRIVATE_REMOTE;
1278 /* release if remote sends us no tones */
1279 if (!p_m_mISDNport->earlyb)
1289 l3m = create_l3msg();
1291 dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, dinfo, sizeof(RELEASE_t), p_m_d_ntmode);
1292 release = (RELEASE_t *)(dmsg->data + headerlen);
1294 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
1296 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); /* normal */
1298 enc_ie_cause(&release->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); /* normal */
1300 add_trace("reason", NULL, "no remote patterns");
1303 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE, l3m);
1305 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1308 /* sending release to endpoint */
1311 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1312 message->param.disconnectinfo.cause = cause;
1313 message->param.disconnectinfo.location = location;
1314 message_put(message);
1316 free_epointlist(p_epointlist);
1318 new_state(PORT_STATE_RELEASE);
1323 /* sending disconnect to active endpoint and release to inactive endpoints */
1324 if (ACTIVE_EPOINT(p_epointlist))
1326 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1327 message->param.disconnectinfo.location = location;
1328 message->param.disconnectinfo.cause = cause;
1329 message_put(message);
1331 while(INACTIVE_EPOINT(p_epointlist))
1333 message = message_create(p_serial, INACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1334 message->param.disconnectinfo.location = location;
1335 message->param.disconnectinfo.cause = cause;
1336 message_put(message);
1338 free_epointid(INACTIVE_EPOINT(p_epointlist));
1340 new_state(PORT_STATE_IN_DISCONNECT);
1343 /* CC_DISCONNECT INDICATION */
1345 void Pdss1::disconnect_ind_i(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1348 void Pdss1::disconnect_ind_i(unsigned long prim, unsigned long dinfo, void *data)
1350 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1351 DISCONNECT_t *disconnect = (DISCONNECT_t *)((unsigned long)data + headerlen);
1353 int location, cause;
1356 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_IND, DIRECTION_IN);
1357 if (p_m_d_collect_cause > 0)
1359 add_trace("old-cause", "location", "%d", p_m_d_collect_location);
1360 add_trace("old-cause", "value", "%d", p_m_d_collect_cause);
1363 dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1365 dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1367 if (location == LOCATION_PRIVATE_LOCAL)
1368 location = LOCATION_PRIVATE_REMOTE;
1371 collect_cause(&p_m_d_collect_cause, &p_m_d_collect_location, cause, location);
1372 add_trace("new-cause", "location", "%d", p_m_d_collect_location);
1373 add_trace("new-cause", "value", "%d", p_m_d_collect_cause);
1378 /* CC_RELEASE INDICATION */
1380 void Pdss1::release_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1383 void Pdss1::release_ind(unsigned long prim, unsigned long dinfo, void *data)
1385 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1387 RELEASE_t *release = (RELEASE_t *)((unsigned long)data + headerlen);
1389 int location, cause;
1390 struct message *message;
1392 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_IND, DIRECTION_IN);
1394 dec_ie_cause(release->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1396 dec_ie_cause(release->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1399 if (location == LOCATION_PRIVATE_LOCAL)
1400 location = LOCATION_PRIVATE_REMOTE;
1405 /* sending release to endpoint */
1408 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1409 message->param.disconnectinfo.cause = cause;
1410 message->param.disconnectinfo.location = location;
1411 message_put(message);
1413 free_epointlist(p_epointlist);
1416 /* only in NT mode we must send release_complete, if we got a release confirm */
1417 if (prim == (CC_RELEASE | CONFIRM))
1419 /* sending release complete */
1420 RELEASE_COMPLETE_t *release_complete;
1423 l3m = create_l3msg();
1425 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
1426 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
1428 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
1430 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16);
1432 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16);
1436 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
1438 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1442 new_state(PORT_STATE_RELEASE);
1446 /* CC_RELEASE_COMPLETE INDICATION (a reject) */
1448 void Pdss1::release_complete_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1451 void Pdss1::release_complete_ind(unsigned long prim, unsigned long dinfo, void *data)
1453 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1454 RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *)((unsigned long)data + headerlen);
1456 int location, cause;
1457 struct message *message;
1459 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_IND, DIRECTION_IN);
1461 dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1463 dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1466 if (location == LOCATION_PRIVATE_LOCAL)
1467 location = LOCATION_PRIVATE_REMOTE;
1472 /* sending release to endpoint */
1475 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1476 message->param.disconnectinfo.cause = cause;
1477 message->param.disconnectinfo.location = location;
1478 message_put(message);
1480 free_epointlist(p_epointlist);
1483 new_state(PORT_STATE_RELEASE);
1489 void Pdss1::t312_timeout_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1492 void Pdss1::t312_timeout_ind(unsigned long prim, unsigned long dinfo, void *data)
1495 struct message *message;
1497 // trace is done at message_isdn()
1499 /* sending release to endpoint */
1502 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1503 if (p_m_d_collect_cause)
1505 message->param.disconnectinfo.cause = p_m_d_collect_cause;
1506 message->param.disconnectinfo.location = p_m_d_collect_location;
1509 message->param.disconnectinfo.cause = CAUSE_NOUSER;
1510 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1512 message_put(message);
1514 free_epointlist(p_epointlist);
1517 new_state(PORT_STATE_RELEASE);
1521 /* CC_NOTIFY INDICATION */
1523 void Pdss1::notify_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1526 void Pdss1::notify_ind(unsigned long prim, unsigned long dinfo, void *data)
1528 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1529 NOTIFY_t *notifying = (NOTIFY_t *)((unsigned long)data + headerlen);
1531 struct message *message;
1532 int notify, type, plan, present;
1533 unsigned char notifyid[sizeof(message->param.notifyinfo.id)];
1535 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_IND, DIRECTION_IN);
1537 dec_ie_notify(notifying->NOTIFY, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
1538 dec_ie_redir_dn(notifying->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, notifyid, sizeof(notifyid));
1540 dec_ie_notify(notifying->NOTIFY, (Q931_info_t *)((unsigned long)data+headerlen), ¬ify);
1541 dec_ie_redir_dn(notifying->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, notifyid, sizeof(notifyid));
1545 if (!ACTIVE_EPOINT(p_epointlist))
1547 /* notification indicator */
1551 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1552 message->param.notifyinfo.notify = notify;
1553 SCPY(message->param.notifyinfo.id, (char *)notifyid);
1554 /* redirection number */
1558 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1561 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1564 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1570 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1571 message->param.notifyinfo.present = INFO_PRESENT_NULL;
1574 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1577 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1580 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1583 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1586 message->param.notifyinfo.isdn_port = p_m_portnum;
1587 message_put(message);
1591 /* CC_HOLD INDICATION */
1592 struct message *message;
1594 void Pdss1::hold_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1597 void Pdss1::hold_ind(unsigned long prim, unsigned long dinfo, void *data)
1599 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1601 // HOLD_t *hold = (HOLD_t *)((unsigned long)data + headerlen);
1602 HOLD_REJECT_t *hold_reject;
1603 HOLD_ACKNOWLEDGE_t *hold_acknowledge;
1605 // class Endpoint *epoint;
1607 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_IND, DIRECTION_IN);
1610 if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold)
1613 l3m = create_l3msg();
1615 dmsg = create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, dinfo, sizeof(HOLD_REJECT_t), p_m_d_ntmode);
1616 hold_reject = (HOLD_REJECT_t *)(dmsg->data + headerlen);
1618 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_REJECT_REQ, DIRECTION_OUT);
1620 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
1622 enc_ie_cause(&hold_reject->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
1624 add_trace("reason", NULL, "no endpoint");
1627 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_HOLD_REJECT, l3m);
1629 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1635 /* notify the hold of call */
1636 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1637 message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1638 message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1639 message_put(message);
1641 /* deactivate bchannel */
1642 chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (hold)", DIRECTION_NONE);
1643 add_trace("disconnect", "channel", "%d", p_m_b_channel);
1647 /* set hold state */
1650 epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
1651 if (epoint && p_m_d_ntmode)
1653 p_m_timeout = p_settings.tout_hold;
1658 /* acknowledge hold */
1660 l3m = create_l3msg();
1662 dmsg = create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE, dinfo, sizeof(HOLD_ACKNOWLEDGE_t), p_m_d_ntmode);
1663 hold_acknowledge = (HOLD_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1665 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1668 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_HOLD_ACKNOWLEDGE, l3m);
1670 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1675 /* CC_RETRIEVE INDICATION */
1677 void Pdss1::retrieve_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1680 void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data)
1682 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1684 RETRIEVE_t *retrieve = (RETRIEVE_t *)((unsigned long)data + headerlen);
1685 RETRIEVE_REJECT_t *retrieve_reject;
1686 RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
1688 struct message *message;
1689 int channel, exclusive, cause;
1692 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_IND, DIRECTION_IN);
1694 dec_ie_channel_id(retrieve->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1696 dec_ie_channel_id(retrieve->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1702 cause = 101; /* incompatible state */
1706 l3m = create_l3msg();
1708 dmsg = create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, dinfo, sizeof(RETRIEVE_REJECT_t), p_m_d_ntmode);
1709 retrieve_reject = (RETRIEVE_REJECT_t *)(dmsg->data + headerlen);
1711 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_REJECT_REQ, DIRECTION_OUT);
1713 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, cause);
1715 enc_ie_cause(&retrieve_reject->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, cause);
1719 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RETRIEVE_REJECT, l3m);
1721 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1727 /* notify the retrieve of call */
1728 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1729 message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1730 message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
1731 message_put(message);
1734 ret = channel = hunt_bchannel(channel, exclusive);
1739 ret = seize_bchannel(channel, 1);
1746 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
1748 /* set hold state */
1752 /* acknowledge retrieve */
1754 l3m = create_l3msg();
1756 dmsg = create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE, dinfo, sizeof(RETRIEVE_ACKNOWLEDGE_t), p_m_d_ntmode);
1757 retrieve_acknowledge = (RETRIEVE_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1759 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1761 enc_ie_channel_id(l3m, 1, p_m_b_channel);
1763 enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
1767 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RETRIEVE_ACKNOWLEDGE, l3m);
1769 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1773 /* CC_SUSPEND INDICATION */
1775 void Pdss1::suspend_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1778 void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data)
1780 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1782 SUSPEND_t *suspend = (SUSPEND_t *)((unsigned long)data + headerlen);
1783 SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
1784 SUSPEND_REJECT_t *suspend_reject;
1786 struct message *message;
1787 class Endpoint *epoint;
1788 unsigned char callid[8];
1790 int ret = -31; /* normal, unspecified */
1792 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_IND, DIRECTION_IN);
1794 dec_ie_call_id(suspend->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1796 dec_ie_call_id(suspend->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1800 if (!ACTIVE_EPOINT(p_epointlist))
1804 l3m = create_l3msg();
1806 dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, dinfo, sizeof(SUSPEND_REJECT_t), p_m_d_ntmode);
1807 suspend_reject = (SUSPEND_REJECT_t *)(dmsg->data + headerlen);
1809 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_REJECT_REQ, DIRECTION_OUT);
1811 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1813 enc_ie_cause(&suspend_reject->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1817 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_SUSPEND_REJECT, l3m);
1819 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1828 /* check if call id is in use */
1829 epoint = epoint_first;
1832 if (epoint->ep_park)
1834 if (epoint->ep_park_len == len)
1835 if (!memcmp(epoint->ep_park_callid, callid, len))
1837 ret = -84; /* call id in use */
1841 epoint = epoint->next;
1844 /* notify the hold of call */
1845 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1846 message->param.notifyinfo.notify = INFO_NOTIFY_USER_SUSPENDED;
1847 message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1848 message_put(message);
1850 /* deactivate bchannel */
1851 chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (suspend)", DIRECTION_NONE);
1852 add_trace("disconnect", "channel", "%d", p_m_b_channel);
1856 /* sending suspend to endpoint */
1857 while (p_epointlist)
1859 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_SUSPEND);
1860 memcpy(message->param.parkinfo.callid, callid, sizeof(message->param.parkinfo.callid));
1861 message->param.parkinfo.len = len;
1862 message_put(message);
1864 free_epointlist(p_epointlist);
1867 /* sending SUSPEND_ACKNOWLEDGE */
1869 l3m = create_l3msg();
1871 dmsg = create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE, dinfo, sizeof(SUSPEND_ACKNOWLEDGE_t), p_m_d_ntmode);
1872 suspend_acknowledge = (SUSPEND_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1874 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1877 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_SUSPEND_ACKNOWLEDGE, l3m);
1879 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1882 new_state(PORT_STATE_RELEASE);
1886 /* CC_RESUME INDICATION */
1888 void Pdss1::resume_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1891 void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data)
1893 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1895 RESUME_t *resume = (RESUME_t *)((unsigned long)data + headerlen);
1896 RESUME_REJECT_t *resume_reject;
1897 RESUME_ACKNOWLEDGE_t *resume_acknowledge;
1899 unsigned char callid[8];
1901 int channel, exclusive;
1902 class Endpoint *epoint;
1903 struct message *message;
1906 /* callref from nt-lib */
1909 /* nt-library now gives us the id via CC_RESUME */
1910 if (dinfo&(~0xff) == 0xff00)
1911 FATAL("l3-stack gives us a process id 0xff00-0xffff\n");
1912 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_CR_IND, DIRECTION_IN);
1914 add_trace("callref", "old", "0x%x", p_m_d_l3id);
1915 add_trace("callref", "new", "0x%x", dinfo);
1917 if (p_m_d_l3id&(~0xff) == 0xff00)
1918 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
1920 p_m_d_ces = resume->ces;
1923 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_IND, DIRECTION_IN);
1925 dec_ie_call_id(resume->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1927 dec_ie_call_id(resume->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1931 /* if blocked, release call */
1932 if (p_m_mISDNport->ifport->block)
1941 /* channel_id (no channel is possible in message) */
1943 channel = -1; /* any channel */
1946 ret = channel = hunt_bchannel(channel, exclusive);
1951 ret = seize_bchannel(channel, 1);
1957 l3m = create_l3msg();
1959 dmsg = create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT, dinfo, sizeof(RESUME_REJECT_t), p_m_d_ntmode);
1960 resume_reject = (RESUME_REJECT_t *)(dmsg->data + headerlen);
1962 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_REJECT_REQ, DIRECTION_OUT);
1964 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1966 enc_ie_cause(&resume_reject->CAUSE, dmsg, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1969 add_trace("reason", NULL, "port blocked");
1972 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RESUME_REJECT, l3m);
1974 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1976 new_state(PORT_STATE_RELEASE);
1980 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
1982 /* create endpoint */
1984 FATAL("Incoming resume but already got an endpoint.\n");
1985 ret = -85; /* no call suspended */
1986 epoint = epoint_first;
1989 if (epoint->ep_park)
1991 ret = -83; /* suspended call exists, but this not */
1992 if (epoint->ep_park_len == len)
1993 if (!memcmp(epoint->ep_park_callid, callid, len))
1996 epoint = epoint->next;
2001 epointlist_new(epoint->ep_serial);
2002 if (!(epoint->portlist_new(p_serial, p_type, p_m_mISDNport->earlyb)))
2003 FATAL("No memory for portlist\n");
2004 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RESUME);
2005 message_put(message);
2007 /* notify the resume of call */
2008 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
2009 message->param.notifyinfo.notify = INFO_NOTIFY_USER_RESUMED;
2010 message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
2011 message_put(message);
2013 /* sending RESUME_ACKNOWLEDGE */
2015 l3m = create_l3msg();
2017 dmsg = create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE, dinfo, sizeof(RESUME_ACKNOWLEDGE_t), p_m_d_ntmode);
2018 resume_acknowledge = (RESUME_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
2020 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_ACKNOWLEDGE_REQ, DIRECTION_OUT);
2022 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2024 enc_ie_channel_id(&resume_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2028 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RESUME_ACKNOWDGE, l3m);
2030 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2033 new_state(PORT_STATE_CONNECT);
2037 /* CC_FACILITY INDICATION */
2039 void Pdss1::facility_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2042 void Pdss1::facility_ind(unsigned long prim, unsigned long dinfo, void *data)
2044 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2045 FACILITY_t *facility = (FACILITY_t *)((unsigned long)data + headerlen);
2047 unsigned char facil[256];
2049 struct message *message;
2051 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_IND, DIRECTION_IN);
2053 dec_ie_facility(facility->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), facil, &facil_len);
2055 dec_ie_facility(facility->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), facil, &facil_len);
2063 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
2064 message->param.facilityinfo.len = facil_len;
2065 memcpy(message->param.facilityinfo.data, facil, facil_len);
2066 message_put(message);
2071 * handler for isdn connections
2072 * incoming information are parsed and sent via message to the endpoint
2074 void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
2081 case CC_TIMEOUT | INDICATION:
2086 timer_hex = *((int *)(((char *)data)/*+headerlen*/));
2088 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2089 timer_hex = *((int *)(((char *)data)+headerlen));
2092 if (timer_hex==0x312 && p_m_d_ntmode)
2094 l1l2l3_trace_header(p_m_mISDNport, this, L3_TIMEOUT_IND, DIRECTION_IN);
2095 add_trace("timer", NULL, "%x", timer_hex);
2097 t312_timeout_ind(prim, dinfo, data);
2101 case CC_SETUP | INDICATION:
2102 if (p_state != PORT_STATE_IDLE)
2104 setup_ind(prim, dinfo, data);
2107 case CC_SETUP | CONFIRM:
2110 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_CR_IND, DIRECTION_IN);
2111 add_trace("callref", "old", "0x%x", p_m_d_l3id);
2112 /* nt-library now gives us a new id via CC_SETUP_CONFIRM */
2113 if ((p_m_d_l3id&0xff00) != 0xff00)
2114 PERROR(" strange setup-procid 0x%x\n", p_m_d_l3id);
2115 p_m_d_l3id = *((int *)(((u_char *)data)+ mISDNUSER_HEAD_SIZE));
2116 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2121 case CC_INFORMATION | INDICATION:
2122 information_ind(prim, dinfo, data);
2125 case CC_SETUP_ACKNOWLEDGE | INDICATION:
2126 if (p_state != PORT_STATE_OUT_SETUP)
2128 PERROR("Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
2131 setup_acknowledge_ind(prim, dinfo, data);
2134 case CC_PROCEEDING | INDICATION:
2135 if (p_state != PORT_STATE_OUT_SETUP
2136 && p_state != PORT_STATE_OUT_OVERLAP)
2138 PERROR("Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
2141 proceeding_ind(prim, dinfo, data);
2144 case CC_ALERTING | INDICATION:
2145 if (p_state != PORT_STATE_OUT_SETUP
2146 && p_state != PORT_STATE_OUT_OVERLAP
2147 && p_state != PORT_STATE_OUT_PROCEEDING)
2149 PERROR("Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
2152 alerting_ind(prim, dinfo, data);
2155 case CC_CONNECT | INDICATION:
2156 if (p_state != PORT_STATE_OUT_SETUP
2157 && p_state != PORT_STATE_OUT_OVERLAP
2158 && p_state != PORT_STATE_OUT_PROCEEDING
2159 && p_state != PORT_STATE_OUT_ALERTING)
2161 PERROR("Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING.\n", p_name);
2164 connect_ind(prim, dinfo, data);
2165 if (p_m_d_notify_pending)
2167 /* send pending notify message during connect */
2168 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2169 message_free(p_m_d_notify_pending);
2170 p_m_d_notify_pending = NULL;
2174 case CC_CONNECT_ACKNOWLEDGE | INDICATION:
2175 case CC_CONNECT | CONFIRM:
2176 if (p_state == PORT_STATE_CONNECT_WAITING)
2177 new_state(PORT_STATE_CONNECT);
2178 if (p_m_d_notify_pending)
2180 /* send pending notify message during connect-ack */
2181 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2182 message_free(p_m_d_notify_pending);
2183 p_m_d_notify_pending = NULL;
2187 case CC_DISCONNECT | INDICATION:
2188 disconnect_ind(prim, dinfo, data);
2191 case CC_RELEASE | CONFIRM:
2192 case CC_RELEASE | INDICATION:
2193 release_ind(prim, dinfo, data);
2196 case CC_RELEASE_COMPLETE | INDICATION:
2197 release_complete_ind(prim, dinfo, data);
2200 case CC_RELEASE_COMPLETE | CONFIRM:
2203 case CC_NOTIFY | INDICATION:
2204 notify_ind(prim, dinfo, data);
2207 case CC_HOLD | INDICATION:
2208 hold_ind(prim, dinfo, data);
2211 case CC_RETRIEVE | INDICATION:
2212 retrieve_ind(prim, dinfo, data);
2215 case CC_SUSPEND | INDICATION:
2216 suspend_ind(prim, dinfo, data);
2219 case CC_RESUME | INDICATION:
2220 resume_ind(prim, dinfo, data);
2223 case CC_FACILITY | INDICATION:
2224 facility_ind(prim, dinfo, data);
2227 case CC_RELEASE_CR | INDICATION:
2228 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_CR_IND, DIRECTION_IN);
2229 add_trace("callref", NULL, "0x%x", p_m_d_l3id);
2233 if ((p_m_d_l3id&0xff00) == 0xff00)
2234 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
2238 //#warning remove me
2239 //PDEBUG(DEBUG_LOG, "JOLLY release cr %d\n", p_serial);
2240 /* sending release to endpoint in case we still have an endpoint
2241 * this is because we don't get any response if a release_complete is received (or a release in release state)
2245 struct message *message;
2246 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
2247 message->param.disconnectinfo.cause = (p_m_d_collect_cause!=CAUSE_NOUSER)?p_m_d_collect_cause:CAUSE_UNSPECIFIED;
2248 message->param.disconnectinfo.location = (p_m_d_collect_cause!=CAUSE_NOUSER)?p_m_d_collect_location:LOCATION_PRIVATE_LOCAL;
2249 message_put(message);
2251 free_epointlist(p_epointlist);
2253 new_state(PORT_STATE_RELEASE);
2257 case CC_NEW_CR | INDICATION:
2258 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_CR_IND, DIRECTION_IN);
2260 add_trace("callref", "old", "0x%x", p_m_d_l3id);
2263 new_l3id = *((int *)(((u_char *)data+mISDNUSER_HEAD_SIZE)));
2264 if (((new_l3id&0xff00)!=0xff00) && ((p_m_d_l3id&0xff00)==0xff00))
2265 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
2270 p_m_d_l3id = new_l3id;
2271 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2276 l1l2l3_trace_header(p_m_mISDNport, this, L3_UNKNOWN, DIRECTION_IN);
2277 add_trace("unhandled", "prim", "0x%x", prim);
2282 void Pdss1::new_state(int state)
2284 // class Endpoint *epoint;
2287 if (state == PORT_STATE_IN_OVERLAP)
2289 p_m_timeout = p_m_mISDNport->ifport->tout_dialing;
2292 if (state != p_state)
2294 if (state == PORT_STATE_IN_SETUP
2295 || state == PORT_STATE_OUT_SETUP
2296 || state == PORT_STATE_IN_OVERLAP
2297 || state == PORT_STATE_OUT_OVERLAP)
2299 p_m_timeout = p_m_mISDNport->ifport->tout_setup;
2302 if (state == PORT_STATE_IN_PROCEEDING
2303 || state == PORT_STATE_OUT_PROCEEDING)
2305 p_m_timeout = p_m_mISDNport->ifport->tout_proceeding;
2308 if (state == PORT_STATE_IN_ALERTING
2309 || state == PORT_STATE_OUT_ALERTING)
2311 p_m_timeout = p_m_mISDNport->ifport->tout_alerting;
2314 if (state == PORT_STATE_CONNECT
2315 || state == PORT_STATE_CONNECT_WAITING)
2319 if (state == PORT_STATE_IN_DISCONNECT
2320 || state == PORT_STATE_OUT_DISCONNECT)
2322 p_m_timeout = p_m_mISDNport->ifport->tout_disconnect;
2327 Port::new_state(state);
2334 int Pdss1::handler(void)
2338 //if (p_m_delete && p_m_d_l3id==0)
2339 // printf("ping! %d", p_serial);
2340 if ((ret = PmISDN::handler()))
2343 /* handle destruction */
2344 if (p_m_delete && p_m_d_l3id==0)
2347 //PDEBUG(DEBUG_LOG, "JOLLY destroy object %d\n", p_serial);
2358 * handles all messages from endpoint
2360 /* MESSAGE_INFORMATION */
2361 void Pdss1::message_information(unsigned long epoint_id, int message_id, union parameter *param)
2366 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2368 INFORMATION_t *information;
2371 if (param->information.id[0]) /* only if we have something to dial */
2374 l3m = create_l3msg();
2376 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2377 information = (INFORMATION_t *)(dmsg->data + headerlen);
2379 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2381 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)param->information.id);
2383 enc_ie_called_pn(&information->CALLED_PN, dmsg, 0, 1, (unsigned char *)param->information.id);
2387 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_INFORMATION, l3m);
2389 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2399 void Pdss1::message_setup(unsigned long epoint_id, int message_id, union parameter *param)
2404 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2406 INFORMATION_t *information;
2409 int plan, type, screen, present, reason;
2410 int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
2411 int channel, exclusive;
2413 struct epoint_list *epointlist;
2415 /* release if port is blocked */
2416 if (p_m_mISDNport->ifport->block)
2418 struct message *message;
2420 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2421 message->param.disconnectinfo.cause = 27; // temp. unavail.
2422 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2423 message_put(message);
2424 new_state(PORT_STATE_RELEASE);
2429 /* copy setup infos to port */
2430 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
2431 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
2432 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
2433 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
2434 // SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
2435 /* screen outgoing caller id */
2436 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
2438 /* only display at connect state: this case happens if endpoint is in connected mode */
2439 if (p_state==PORT_STATE_CONNECT)
2441 if (p_type!=PORT_TYPE_DSS1_NT_OUT
2442 && p_type!=PORT_TYPE_DSS1_NT_IN)
2444 if (p_callerinfo.display[0])
2446 /* sending information */
2448 l3m = create_l3msg();
2450 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2451 information = (INFORMATION_t *)(dmsg->data + headerlen);
2453 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2456 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2458 enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_callerinfo.display);
2462 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_INFORMATION, l3m);
2464 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2470 /* attach only if not already */
2471 epointlist = p_epointlist;
2474 if (epointlist->epoint_id == epoint_id)
2476 epointlist = epointlist->next;
2479 epointlist_new(epoint_id);
2485 channel = p_m_b_channel;
2486 exclusive = p_m_b_exclusive;
2488 channel = CHANNEL_ANY;
2489 /* nt-port with no channel, not reserverd */
2490 if (!p_m_b_channel && !p_m_b_reserve && p_type==PORT_TYPE_DSS1_NT_OUT)
2491 channel = CHANNEL_NO;
2494 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_CR_REQ, DIRECTION_OUT);
2500 if (p_m_mISDNport->procids[i] == 0)
2506 struct message *message;
2508 add_trace("callref", NULL, "no free id");
2510 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2511 message->param.disconnectinfo.cause = 47;
2512 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2513 message_put(message);
2514 new_state(PORT_STATE_RELEASE);
2518 p_m_mISDNport->procids[i] = 1;
2519 p_m_d_l3id = 0xff00 | i;
2523 /* if we are in te-mode, we need to create a process first */
2524 if (newteid++ > 0x7fff)
2526 p_m_d_l3id = (entity<<16) | newteid;
2527 /* preparing message */
2528 ncr.prim = CC_NEW_CR | REQUEST;
2529 ncr.addr = p_m_mISDNport->upper_id | FLG_MSG_DOWN;
2530 ncr.dinfo = p_m_d_l3id;
2533 mISDN_write(mISDNdevice, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
2537 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2540 /* preparing setup message */
2542 l3m = create_l3msg();
2544 dmsg = create_l3msg(CC_SETUP | REQUEST, MT_SETUP, p_m_d_l3id, sizeof(SETUP_t), p_m_d_ntmode);
2545 setup = (SETUP_t *)(dmsg->data + headerlen);
2547 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_REQ, DIRECTION_OUT);
2548 /* channel information */
2549 if (channel >= 0) /* it should */
2552 enc_ie_channel_id(l3m, exclusive, channel);
2554 enc_ie_channel_id(&setup->CHANNEL_ID, dmsg, exclusive, channel);
2557 /* caller information */
2559 switch (p_callerinfo.ntype)
2561 case INFO_NTYPE_INTERNATIONAL:
2564 case INFO_NTYPE_NATIONAL:
2567 case INFO_NTYPE_SUBSCRIBER:
2570 default: /* INFO_NTYPE_UNKNOWN */
2574 switch (p_callerinfo.screen)
2576 case INFO_SCREEN_USER:
2579 default: /* INFO_SCREEN_NETWORK */
2583 switch (p_callerinfo.present)
2585 case INFO_PRESENT_RESTRICTED:
2588 case INFO_PRESENT_NOTAVAIL:
2591 default: /* INFO_PRESENT_ALLOWED */
2597 enc_ie_calling_pn(l3m, type, plan, present, screen, (unsigned char *)p_callerinfo.id);
2599 enc_ie_calling_pn(&setup->CALLING_PN, dmsg, type, plan, present, screen, (unsigned char *)p_callerinfo.id);
2601 /* dialing information */
2602 if (p_dialinginfo.id[0]) /* only if we have something to dial */
2605 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id);
2607 enc_ie_called_pn(&setup->CALLED_PN, dmsg, 0, 1, (unsigned char *)p_dialinginfo.id);
2610 /* sending complete */
2611 if (p_dialinginfo.sending_complete)
2613 enc_ie_complete(l3m, 1);
2615 enc_ie_complete(&setup->COMPLETE, dmsg, 1);
2617 /* sending user-user */
2618 if (param->setup.useruser.len)
2621 enc_ie_useruser(l3m, param->setup.useruser.protocol, param->setup.useruser.data, param->setup.useruser.len);
2623 enc_ie_useruser(&setup->USER_USER, dmsg, param->setup.useruser.protocol, param->setup.useruser.data, param->setup.useruser.len);
2626 /* redirecting number */
2628 switch (p_redirinfo.ntype)
2630 case INFO_NTYPE_INTERNATIONAL:
2633 case INFO_NTYPE_NATIONAL:
2636 case INFO_NTYPE_SUBSCRIBER:
2639 default: /* INFO_NTYPE_UNKNOWN */
2643 switch (p_redirinfo.screen)
2645 case INFO_SCREEN_USER:
2648 default: /* INFO_SCREE_NETWORK */
2652 switch (p_redirinfo.reason)
2654 case INFO_REDIR_BUSY:
2657 case INFO_REDIR_NORESPONSE:
2660 case INFO_REDIR_UNCONDITIONAL:
2663 case INFO_REDIR_CALLDEFLECT:
2666 case INFO_REDIR_OUTOFORDER:
2669 default: /* INFO_REDIR_UNKNOWN */
2673 switch (p_redirinfo.present)
2675 case INFO_PRESENT_NULL: /* no redir at all */
2682 case INFO_PRESENT_RESTRICTED:
2685 case INFO_PRESENT_NOTAVAIL:
2688 default: /* INFO_PRESENT_ALLOWED */
2692 /* sending redirecting number only in ntmode */
2693 if (type >= 0 && p_m_d_ntmode)
2695 enc_ie_redir_nr(l3m, type, plan, present, screen, reason, (unsigned char *)p_redirinfo.id);
2697 enc_ie_redir_nr(&setup->REDIR_NR, dmsg, type, plan, present, screen, reason, (unsigned char *)p_redirinfo.id);
2699 /* bearer capability */
2700 //printf("hlc=%d\n",p_capainfo.hlc);
2702 capability = p_capainfo.bearer_capa;
2703 mode = p_capainfo.bearer_mode;
2704 rate = (mode==INFO_BMODE_CIRCUIT)?0x10:0x00;
2705 switch (p_capainfo.bearer_info1)
2707 case INFO_INFO1_NONE:
2711 user = p_capainfo.bearer_info1 & 0x7f;
2715 enc_ie_bearer(l3m, coding, capability, mode, rate, -1, user);
2717 enc_ie_bearer(&setup->BEARER, dmsg, coding, capability, mode, rate, -1, user);
2725 hlc = p_capainfo.hlc & 0x7f;
2727 if (p_capainfo.exthlc)
2728 exthlc = p_capainfo.exthlc & 0x7f;
2730 enc_ie_hlc(l3m, coding, interpretation, presentation, hlc, exthlc);
2732 enc_ie_hlc(&setup->HLC, dmsg, coding, interpretation, presentation, hlc, exthlc);
2737 if (p_callerinfo.display[0] && p_m_d_ntmode)
2739 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2741 enc_ie_display(&setup->DISPLAY, dmsg, (unsigned char *)p_callerinfo.display);
2743 /* nt-mode: CNIP (calling name identification presentation) */
2744 // if (p_callerinfo.name[0] && p_m_d_ntmode)
2745 // enc_facility_centrex(&setup->FACILITY, dmsg, (unsigned char *)p_callerinfo.name, 1);
2748 /* send setup message now */
2750 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_SETUP, l3m);
2752 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2755 new_state(PORT_STATE_OUT_SETUP);
2758 /* MESSAGE_FACILITY */
2759 void Pdss1::message_facility(unsigned long epoint_id, int message_id, union parameter *param)
2764 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2766 FACILITY_t *facility;
2769 /* facility will not be sent to external lines */
2773 /* sending facility */
2775 l3m = create_l3msg();
2777 dmsg = create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, p_m_d_l3id, sizeof(FACILITY_t), p_m_d_ntmode);
2778 facility = (FACILITY_t *)(dmsg->data + headerlen);
2780 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2782 enc_ie_facility(l3m, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len);
2784 enc_ie_facility(&facility->FACILITY, dmsg, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len);
2788 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_FACILITY, l3m);
2790 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2794 /* MESSAGE_NOTIFY */
2795 void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parameter *param)
2800 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2802 INFORMATION_t *information;
2803 NOTIFY_t *notification;
2806 int plan, type = -1, present;
2808 if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
2809 notify = param->notifyinfo.notify & 0x7f;
2812 if (p_state != PORT_STATE_CONNECT)
2814 /* notify only allowed in active state */
2820 switch (param->notifyinfo.ntype)
2822 case INFO_NTYPE_INTERNATIONAL:
2825 case INFO_NTYPE_NATIONAL:
2828 case INFO_NTYPE_SUBSCRIBER:
2831 default: /* INFO_NTYPE_UNKNOWN */
2835 switch (param->notifyinfo.present)
2837 case INFO_PRESENT_NULL: /* no redir at all */
2842 case INFO_PRESENT_RESTRICTED:
2845 case INFO_PRESENT_NOTAVAIL:
2848 default: /* INFO_PRESENT_ALLOWED */
2854 if (notify<0 && !param->notifyinfo.display[0])
2856 /* nothing to notify, nothing to display */
2862 if (p_state!=PORT_STATE_CONNECT)
2864 /* queue notification */
2865 if (p_m_d_notify_pending)
2866 message_free(p_m_d_notify_pending);
2867 p_m_d_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
2868 memcpy(&p_m_d_notify_pending->param, param, sizeof(union parameter));
2871 /* sending notification */
2873 l3m = create_l3msg();
2875 dmsg = create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, p_m_d_l3id, sizeof(NOTIFY_t), p_m_d_ntmode);
2876 notification = (NOTIFY_t *)(dmsg->data + headerlen);
2878 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
2880 enc_ie_notify(l3m, notify);
2882 enc_ie_notify(¬ification->NOTIFY, dmsg, notify);
2884 /* sending redirection number only in ntmode */
2885 if (type >= 0 && p_m_d_ntmode)
2887 enc_ie_redir_dn(l3m, type, plan, present, (unsigned char *)param->notifyinfo.id);
2889 enc_ie_redir_dn(¬ification->REDIR_DN, dmsg, type, plan, present, (unsigned char *)param->notifyinfo.id);
2891 if (param->notifyinfo.display[0] && p_m_d_ntmode)
2893 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2895 enc_ie_display(¬ification->DISPLAY, dmsg, (unsigned char *)param->notifyinfo.display);
2899 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_NOTIFICATION, l3m);
2901 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2904 } else if (p_m_d_ntmode)
2906 /* sending information */
2908 l3m = create_l3msg();
2910 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2911 information = (INFORMATION_t *)(dmsg->data + headerlen);
2913 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2915 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2917 enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)param->notifyinfo.display);
2921 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_INFORMATION, l3m);
2923 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2928 /* MESSAGE_OVERLAP */
2929 void Pdss1::message_overlap(unsigned long epoint_id, int message_id, union parameter *param)
2934 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2936 SETUP_ACKNOWLEDGE_t *setup_acknowledge;
2939 /* sending setup_acknowledge */
2941 l3m = create_l3msg();
2943 dmsg = create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE, p_m_d_l3id, sizeof(SETUP_ACKNOWLEDGE_t), p_m_d_ntmode);
2944 setup_acknowledge = (SETUP_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
2946 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_REQ, DIRECTION_OUT);
2947 /* channel information */
2948 if (p_state == PORT_STATE_IN_SETUP)
2950 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2952 enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2954 /* progress information */
2955 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2956 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2957 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2958 if (p_m_mISDNport->tones)
2960 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
2962 enc_ie_progress(&setup_acknowledge->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2966 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_SETUP_ACKNOWLEDGE, l3m);
2968 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2971 new_state(PORT_STATE_IN_OVERLAP);
2974 /* MESSAGE_PROCEEDING */
2975 void Pdss1::message_proceeding(unsigned long epoint_id, int message_id, union parameter *param)
2980 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2982 CALL_PROCEEDING_t *proceeding;
2985 /* sending proceeding */
2987 l3m = create_l3msg();
2989 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
2990 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
2992 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2993 /* channel information */
2994 if (p_state == PORT_STATE_IN_SETUP)
2996 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2998 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3000 /* progress information */
3001 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3002 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3003 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3004 if (p_m_mISDNport->tones)
3006 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3008 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3012 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_PROCEEDING, l3m);
3014 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3017 new_state(PORT_STATE_IN_PROCEEDING);
3020 /* MESSAGE_ALERTING */
3021 void Pdss1::message_alerting(unsigned long epoint_id, int message_id, union parameter *param)
3026 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
3028 ALERTING_t *alerting;
3031 /* NT-MODE in setup state we must send PROCEEDING first */
3032 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
3034 CALL_PROCEEDING_t *proceeding;
3036 /* sending proceeding */
3038 l3m = create_l3msg();
3040 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
3041 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
3043 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
3044 /* channel information */
3046 enc_ie_channel_id(l3m, 1, p_m_b_channel);
3048 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3050 /* progress information */
3051 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3052 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3053 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3055 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3057 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3061 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_PROCEEDING, l3m);
3063 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3065 new_state(PORT_STATE_IN_PROCEEDING);
3068 /* sending alerting */
3070 l3m = create_l3msg();
3072 dmsg = create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING, p_m_d_l3id, sizeof(ALERTING_t), p_m_d_ntmode);
3073 alerting = (ALERTING_t *)(dmsg->data + headerlen);
3075 l1l2l3_trace_header(p_m_mISDNport, this, L3_ALERTING_REQ, DIRECTION_OUT);
3076 /* channel information */
3077 if (p_state == PORT_STATE_IN_SETUP)
3079 enc_ie_channel_id(l3m, 1, p_m_b_channel);
3081 enc_ie_channel_id(&alerting->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3083 /* progress information */
3084 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3085 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3086 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3087 if (p_m_mISDNport->tones)
3089 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3091 enc_ie_progress(&alerting->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3095 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_ALERTING, l3m);
3097 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3100 new_state(PORT_STATE_IN_ALERTING);
3103 /* MESSAGE_CONNECT */
3104 void Pdss1::message_connect(unsigned long epoint_id, int message_id, union parameter *param)
3109 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
3111 INFORMATION_t *information;
3114 int type, plan, present, screen;
3115 class Endpoint *epoint;
3117 /* NT-MODE in setup state we must send PROCEEDING first */
3118 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
3120 CALL_PROCEEDING_t *proceeding;
3122 /* sending proceeding */
3124 l3m = create_l3msg();
3126 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
3127 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
3129 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
3130 /* channel information */
3132 enc_ie_channel_id(l3m, 1, p_m_b_channel);
3134 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3136 // /* progress information */
3137 // if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3138 // || p_capainfo.bearer_capa==INFO_BC_AUDIO
3139 // || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3141 // enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3143 // enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3147 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_PROCEEDING, l3m);
3149 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3151 new_state(PORT_STATE_IN_PROCEEDING);
3154 /* copy connected information */
3155 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
3156 /* screen outgoing caller id */
3157 do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface);
3159 /* only display at connect state */
3160 if (p_state == PORT_STATE_CONNECT)
3161 if (p_connectinfo.display[0])
3163 /* sending information */
3165 l3m = create_l3msg();
3167 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
3168 information = (INFORMATION_t *)(dmsg->data + headerlen);
3170 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
3173 enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
3175 enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_connectinfo.display);
3179 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_INFORMATION, l3m);
3181 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3186 if (p_state!=PORT_STATE_IN_SETUP && p_state!=PORT_STATE_IN_OVERLAP && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING)
3188 /* connect command only possible in setup, proceeding or alerting state */
3192 /* preparing connect message */
3194 l3m = create_l3msg();
3196 dmsg = create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT, p_m_d_l3id, sizeof(CONNECT_t), p_m_d_ntmode);
3197 connect = (CONNECT_t *)(dmsg->data + headerlen);
3199 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_REQ, DIRECTION_OUT);
3200 /* connect information */
3202 switch (p_connectinfo.ntype)
3204 case INFO_NTYPE_INTERNATIONAL:
3207 case INFO_NTYPE_NATIONAL:
3210 case INFO_NTYPE_SUBSCRIBER:
3213 default: /* INFO_NTYPE_UNKNOWN */
3217 switch (param->connectinfo.screen)
3219 case INFO_SCREEN_USER:
3222 default: /* INFO_SCREE_NETWORK */
3226 switch (p_connectinfo.present)
3228 case INFO_PRESENT_NULL: /* no colp at all */
3234 case INFO_PRESENT_RESTRICTED:
3237 case INFO_PRESENT_NOTAVAIL:
3240 default: /* INFO_PRESENT_ALLOWED */
3246 enc_ie_connected_pn(l3m, type, plan, present, screen, (unsigned char *)p_connectinfo.id);
3248 enc_ie_connected_pn(&connect->CONNECT_PN, dmsg, type, plan, present, screen, (unsigned char *)p_connectinfo.id);
3251 if (p_connectinfo.display[0] && p_m_d_ntmode)
3253 enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
3255 enc_ie_display(&connect->DISPLAY, dmsg, (unsigned char *)p_connectinfo.display);
3257 /* nt-mode: CONP (connected name identification presentation) */
3258 // if (p_connectinfo.name[0] && p_m_d_ntmode)
3259 // enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
3263 epoint = find_epoint_id(epoint_id);
3265 enc_ie_date(l3m, now, p_settings.no_seconds);
3267 enc_ie_date(&connect->DATE, dmsg, now, p_settings.no_seconds);
3271 /* finally send message */
3273 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_CONNECT, l3m);
3275 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3279 new_state(PORT_STATE_CONNECT);
3281 new_state(PORT_STATE_CONNECT_WAITING);
3285 /* MESSAGE_DISCONNECT */
3286 void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union parameter *param)
3291 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
3293 DISCONNECT_t *disconnect;
3294 RELEASE_COMPLETE_t *release_complete;
3296 struct message *message;
3299 /* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
3300 // if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
3301 if (/* ||*/ p_state==PORT_STATE_OUT_SETUP)
3303 /* sending release to endpoint */
3306 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
3307 message->param.disconnectinfo.cause = 16;
3308 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
3309 message_put(message);
3311 free_epointlist(p_epointlist);
3313 /* sending release */
3315 l3m = create_l3msg();
3317 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
3318 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
3320 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
3323 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3325 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3329 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
3331 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3333 new_state(PORT_STATE_RELEASE);
3338 /* workarround: NT-MODE in setup state we must send PROCEEDING first to make it work */
3339 if (p_state==PORT_STATE_IN_SETUP)
3341 CALL_PROCEEDING_t *proceeding;
3343 /* sending proceeding */
3345 l3m = create_l3msg();
3347 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
3348 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
3350 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
3351 /* channel information */
3353 enc_ie_channel_id(l3m, 1, p_m_b_channel);
3355 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3357 /* progress information */
3358 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3359 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3360 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3362 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3364 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3368 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_PROCEEDING, l3m);
3370 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3372 new_state(PORT_STATE_IN_PROCEEDING);
3375 /* sending disconnect */
3377 l3m = create_l3msg();
3379 dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode);
3380 disconnect = (DISCONNECT_t *)(dmsg->data + headerlen);
3382 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
3383 /* progress information */
3384 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3385 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3386 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3387 if (p_m_mISDNport->tones)
3389 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3391 enc_ie_progress(&disconnect->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3395 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3397 enc_ie_cause(&disconnect->CAUSE, dmsg, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3400 if (param->disconnectinfo.display[0])
3401 p = param->disconnectinfo.display;
3402 if (p) if (*p && p_m_d_ntmode)
3404 enc_ie_display(l3m, (unsigned char *)p);
3406 enc_ie_display(&disconnect->DISPLAY, dmsg, (unsigned char *)p);
3410 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_DISCONNECT, l3m);
3412 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3414 new_state(PORT_STATE_OUT_DISCONNECT);
3417 /* MESSAGE_RELEASE */
3418 void Pdss1::message_release(unsigned long epoint_id, int message_id, union parameter *param)
3423 int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
3426 RELEASE_COMPLETE_t *release_complete;
3427 DISCONNECT_t *disconnect;
3429 class Endpoint *epoint;
3433 * we may only release during incoming disconnect state.
3434 * this means that the endpoint doesnt require audio anymore
3436 if (p_state == PORT_STATE_IN_DISCONNECT
3437 || p_state == PORT_STATE_OUT_DISCONNECT)
3439 /* sending release */
3441 l3m = create_l3msg();
3443 dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, p_m_d_l3id, sizeof(RELEASE_t), p_m_d_ntmode);
3444 release = (RELEASE_t *)(dmsg->data + headerlen);
3446 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
3449 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3451 enc_ie_cause(&release->CAUSE, dmsg, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3455 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE, l3m);
3457 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3459 new_state(PORT_STATE_RELEASE);
3461 free_epointid(epoint_id);
3462 // wait for callref to be released
3467 * if we are on incoming call setup, we may reject by sending a release_complete
3468 * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
3470 if (p_state==PORT_STATE_IN_SETUP
3471 || p_state==PORT_STATE_OUT_SETUP)
3472 // // NOTE: a bug in mISDNuser (see disconnect_req_out !!!)
3473 // || p_state==PORT_STATE_OUT_DISCO)
3475 //#warning remove me
3476 //PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
3477 /* sending release complete */
3479 l3m = create_l3msg();
3481 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
3482 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
3484 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
3487 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3489 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3493 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_RELEASE_COMPLETE, l3m);
3495 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3497 new_state(PORT_STATE_RELEASE);
3499 free_epointid(epoint_id);
3501 /* remove process */
3502 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_CR_REQ, DIRECTION_OUT);
3503 add_trace("callref", NULL, "0x%x", p_m_d_l3id);
3507 if ((p_m_d_l3id&0xff00) == 0xff00)
3508 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
3513 // wait for callref to be released
3518 wirklich erst proceeding?:
3519 /* NT-MODE in setup state we must send PROCEEDING first */
3520 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
3522 CALL_PROCEEDING_t *proceeding;
3524 /* sending proceeding */
3526 l3m = create_l3msg();
3528 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
3529 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
3531 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
3532 /* channel information */
3534 enc_ie_channel_id(l3m, 1, p_m_b_channel);
3536 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3538 /* progress information */
3539 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3540 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3541 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3543 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3545 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3549 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_PROCEEDING, l3m);
3551 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3556 /* sending disconnect */
3558 l3m = create_l3msg();
3560 dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode);
3561 disconnect = (DISCONNECT_t *)(dmsg->data + headerlen);
3563 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
3564 /* progress information */
3565 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3566 || p_capainfo.bearer_capa==INFO_BC_AUDIO
3567 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3568 if (p_m_mISDNport->tones)
3570 enc_ie_progress(l3m, 0, p_m_d_ntmode?1:5, 8);
3572 enc_ie_progress(&disconnect->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3576 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3578 enc_ie_cause(&disconnect->CAUSE, dmsg, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3581 epoint = find_epoint_id(epoint_id);
3582 if (param->disconnectinfo.display[0])
3583 p = param->disconnectinfo.display;
3584 if (p) if (*p && p_m_d_ntmode)
3586 enc_ie_display(l3m, (unsigned char *)p);
3588 enc_ie_display(&disconnect->DISPLAY, dmsg, (unsigned char *)p);
3592 p_m_mISDNport->layer3->to_layer3(p_m_mISDNport->layer3, MT_DISCONNECT, l3m);
3594 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3596 new_state(PORT_STATE_OUT_DISCONNECT);
3598 free_epointid(epoint_id);
3599 // wait for release and callref to be released
3600 //#warning remove me
3601 //PDEBUG(DEBUG_LOG, "JOLLY sending disconnect %d\n", p_serial);
3606 * endpoint sends messages to the port
3608 int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
3610 struct message *message;
3612 if (PmISDN::message_epoint(epoint_id, message_id, param))
3617 case MESSAGE_INFORMATION: /* overlap dialing */
3618 if (p_type==PORT_TYPE_DSS1_NT_OUT
3619 && p_state!=PORT_STATE_OUT_OVERLAP
3620 && p_state!=PORT_STATE_CONNECT
3621 && p_state!=PORT_STATE_OUT_DISCONNECT
3622 && p_state!=PORT_STATE_IN_DISCONNECT)
3626 if (p_type==PORT_TYPE_DSS1_TE_OUT
3627 && p_state!=PORT_STATE_OUT_OVERLAP
3628 && p_state!=PORT_STATE_OUT_PROCEEDING
3629 && p_state!=PORT_STATE_OUT_ALERTING
3630 && p_state!=PORT_STATE_CONNECT
3631 && p_state!=PORT_STATE_OUT_DISCONNECT
3632 && p_state!=PORT_STATE_IN_DISCONNECT)
3636 if ((p_type==PORT_TYPE_DSS1_NT_IN || p_type==PORT_TYPE_DSS1_TE_IN)
3637 && p_state!=PORT_STATE_IN_OVERLAP
3638 && p_state!=PORT_STATE_IN_PROCEEDING
3639 && p_state!=PORT_STATE_IN_ALERTING
3640 && p_state!=PORT_STATE_CONNECT
3641 && p_state!=PORT_STATE_CONNECT_WAITING
3642 && p_state!=PORT_STATE_OUT_DISCONNECT
3643 && p_state!=PORT_STATE_IN_DISCONNECT)
3647 message_information(epoint_id, message_id, param);
3650 case MESSAGE_SETUP: /* dial-out command received from epoint */
3651 if (p_state!=PORT_STATE_IDLE
3652 && p_state!=PORT_STATE_CONNECT)
3654 PERROR("Pdss1(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
3657 if (p_epointlist && p_state==PORT_STATE_IDLE)
3658 FATAL("Pdss1(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
3659 /* note: pri is a special case, because links must be up for pri */
3660 if (p_m_mISDNport->l1link || p_m_mISDNport->pri || !p_m_mISDNport->ntmode || p_state!=PORT_STATE_IDLE)
3662 /* LAYER 1 is up, or we may send */
3663 message_setup(epoint_id, message_id, param);
3666 /* LAYER 1 id down, so we queue */
3667 p_m_d_queue = message_create(epoint_id, p_serial, EPOINT_TO_PORT, message_id);
3668 memcpy(&p_m_d_queue->param, param, sizeof(union parameter));
3670 if (!(epointlist_new(epoint_id)))
3671 FATAL("No memory for epointlist\n");
3673 PDEBUG(DEBUG_ISDN, "the L1 is down, we try to establish the link NT portnum=%d (%s).\n", p_m_mISDNport->portnum, p_name);
3674 act.prim = PH_ACTIVATE | REQUEST;
3675 act.addr = p_m_mISDNport->upper_id | FLG_MSG_DOWN;
3678 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3679 l1l2l3_trace_header(p_m_mISDNport, this, L1_ACTIVATE_REQ, DIRECTION_OUT);
3681 // /* set timeout */
3682 // p_m_mISDNport->l1timeout = now+3;
3686 case MESSAGE_NOTIFY: /* display and notifications */
3687 message_notify(epoint_id, message_id, param);
3690 case MESSAGE_FACILITY: /* facility message */
3691 message_facility(epoint_id, message_id, param);
3694 case MESSAGE_OVERLAP: /* more information is needed */
3695 if (p_state!=PORT_STATE_IN_SETUP)
3699 message_overlap(epoint_id, message_id, param);
3702 case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
3703 if (p_state!=PORT_STATE_IN_SETUP
3704 && p_state!=PORT_STATE_IN_OVERLAP)
3708 message_proceeding(epoint_id, message_id, param);
3711 case MESSAGE_ALERTING: /* call of endpoint is ringing */
3712 if (p_state!=PORT_STATE_IN_SETUP
3713 && p_state!=PORT_STATE_IN_OVERLAP
3714 && p_state!=PORT_STATE_IN_PROCEEDING)
3718 message_alerting(epoint_id, message_id, param);
3721 case MESSAGE_CONNECT: /* call of endpoint is connected */
3722 if (p_state!=PORT_STATE_IN_SETUP
3723 && p_state!=PORT_STATE_IN_OVERLAP
3724 && p_state!=PORT_STATE_IN_PROCEEDING
3725 && p_state!=PORT_STATE_IN_ALERTING
3726 && !(p_state==PORT_STATE_CONNECT && p_m_d_ntmode))
3730 message_connect(epoint_id, message_id, param);
3733 case MESSAGE_DISCONNECT: /* call has been disconnected */
3734 if (p_state!=PORT_STATE_IN_SETUP
3735 && p_state!=PORT_STATE_IN_OVERLAP
3736 && p_state!=PORT_STATE_IN_PROCEEDING
3737 && p_state!=PORT_STATE_IN_ALERTING
3738 && p_state!=PORT_STATE_OUT_SETUP
3739 && p_state!=PORT_STATE_OUT_OVERLAP
3740 && p_state!=PORT_STATE_OUT_PROCEEDING
3741 && p_state!=PORT_STATE_OUT_ALERTING
3742 && p_state!=PORT_STATE_CONNECT
3743 && p_state!=PORT_STATE_CONNECT_WAITING)
3747 message_disconnect(epoint_id, message_id, param);
3750 case MESSAGE_RELEASE: /* release isdn port */
3751 if (p_state==PORT_STATE_RELEASE)
3755 message_release(epoint_id, message_id, param);
3759 PERROR("Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message);
3768 * data from isdn-stack (layer-3) to pbx (port class)
3771 int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
3777 PDEBUG(DEBUG_ISDN, "cmd(0x%x) pid(0x%x)\n", cmd, pid);
3779 /* find Port object of type ISDN */
3784 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT)
3786 pdss1 = (class Pdss1 *)port;
3787 /* check out correct stack and id */
3788 if (pdss1->p_m_mISDNport == mISDNport
3789 && pdss1->p_m_d_l3id == pid)
3791 /* found port, the message belongs to */
3798 /* aktueller prozess */
3801 /* if process id is master process, but a child disconnects */
3802 #warning hier das abfragen des child processes
3805 if (cmd == MT_DISCONNECT)
3807 /* send special indication for child disconnect */
3808 pdss1->disconnect_ind_i(cmd, pid, l3m);
3811 // ignoring other messages from child processes
3814 /* if process id and layer 3 id matches */
3815 if (pid == pdss1->p_m_d_l3id)
3817 pdss1->message_isdn(cmd, pid, l3m);
3826 /* creating port object */
3827 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3828 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0)))
3830 FATAL("Cannot create Port instance.\n");
3831 pdss1->message_isdn(cmd, pid, l3m);
3835 /* creating port object */
3836 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3837 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0)))
3838 FATAL("Cannot create Port instance.\n");
3839 pdss1->message_isdn(cmd, pid, l3m);
3843 PERROR("unhandled message from stack: call ref released (l3id=0x%x)\n", hh->dinfo);
3846 case MT_RELEASE_COMPLETE:
3847 PERROR("must be ignored by stack, not sent to app\n");
3851 // facility als broadcast
3855 PERROR("unhandled message: cmd(0x%x) pid(0x%x)\n", cmd, pid);
3859 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT)
3861 pdss1 = (class Pdss1 *)port;
3862 /* check out correct stack */
3863 if (pdss1->p_m_mISDNport == mISDNport)
3864 /* check out correct id */
3865 PERROR("unhandled message: pid=%x is not associated with port-dinfo=%x\n", pid, pdss1->p_m_d_l3id);
3874 /* NOTE: nt mode use mISDNuser_head_t as header */
3875 int stack2manager_nt(void *dat, void *arg)
3879 manager_t *mgr = (manager_t *)dat;
3880 msg_t *msg = (msg_t *)arg;
3881 mISDNuser_head_t *hh;
3882 struct mISDNport *mISDNport;
3888 /* note: nst is the first data feld of mISDNport */
3889 mISDNport = (struct mISDNport *)mgr->nst;
3891 hh = (mISDNuser_head_t *)msg->data;
3892 PDEBUG(DEBUG_ISDN, "prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, msg->len);
3894 /* find Port object of type ISDN */
3898 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT)
3900 pdss1 = (class Pdss1 *)port;
3901 //PDEBUG(DEBUG_ISDN, "comparing dinfo = 0x%x with l3id 0x%x\n", hh->dinfo, pdss1->p_m_d_l3id);
3902 /* check out correct stack */
3903 if (pdss1->p_m_mISDNport == mISDNport)
3904 /* check out correct id */
3905 if ((pdss1->p_m_d_l3id&0x0000ff00) != 0x000ff00)
3907 /* a single process */
3908 if (hh->dinfo == pdss1->p_m_d_l3id)
3910 /* found port, the message belongs to */
3915 /* a broadcast process */
3916 if ((hh->dinfo&0xffff0000) == (pdss1->p_m_d_l3id&0xffff0000))
3918 /* found port, the message belongs to */
3927 //printf("%x %x\n", hh->dinfo, pdss1->p_m_d_l3id);
3928 /* if process id is master process, but a child disconnects */
3929 if ((hh->dinfo&0x0000ff00)!=0x0000ff00 && (pdss1->p_m_d_l3id&0x0000ff00)==0x0000ff00)
3931 if (hh->prim == (CC_DISCONNECT|INDICATION))
3933 /* send special indication for child disconnect */
3934 pdss1->disconnect_ind_i(hh->prim, hh->dinfo, msg->data);
3938 // ignoring other messages from child processes
3942 /* if process id and layer 3 id matches */
3943 if (hh->dinfo == pdss1->p_m_d_l3id)
3945 pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
3954 case MGR_SHORTSTATUS | INDICATION:
3955 case MGR_SHORTSTATUS | CONFIRM:
3957 case SSTATUS_L2_ESTABLISHED:
3959 case SSTATUS_L2_RELEASED:
3964 case DL_ESTABLISH | INDICATION:
3965 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
3967 case DL_ESTABLISH | CONFIRM:
3968 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_CON, DIRECTION_IN);
3970 add_trace("tei", NULL, "%d", hh->dinfo);
3972 if (mISDNport->ptp && hh->dinfo == 0)
3974 if (mISDNport->l2establish)
3976 mISDNport->l2establish = 0;
3977 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
3979 mISDNport->l2link = 1;
3980 if (mISDNport->pri);
3981 mISDNport->l1link = 1; /* this is a hack, we also assume L1 to be active */
3985 case DL_RELEASE | INDICATION:
3986 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
3988 case DL_RELEASE | CONFIRM:
3989 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_CON, DIRECTION_IN);
3991 add_trace("tei", NULL, "%d", hh->dinfo);
3993 if (mISDNport->ptp && hh->dinfo == 0)
3995 mISDNport->l2link = 0;
3996 time(&mISDNport->l2establish);
3997 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
4001 case CC_SETUP | INDICATION:
4002 /* creating port object */
4003 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
4004 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0)))
4006 FATAL("Cannot create Port instance.\n");
4007 pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
4010 case CC_RESUME | INDICATION:
4011 /* creating port object */
4012 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
4013 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0)))
4014 FATAL("Cannot create Port instance.\n");
4015 pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
4018 case CC_RELEASE_CR | INDICATION:
4019 PERROR("unhandled message from stack: call ref released (l3id=0x%x)\n", hh->dinfo);
4022 case CC_RELEASE_COMPLETE | INDICATION:
4025 case CC_FACILITY | INDICATION:
4029 PERROR("unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, msg->len);
4033 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT)
4035 pdss1 = (class Pdss1 *)port;
4036 //PDEBUG(DEBUG_ISDN, "comparing dinfo = 0x%x with l3id 0x%x\n", hh->dinfo, pdss1->p_m_d_l3id);
4037 /* check out correct stack */
4038 if (pdss1->p_m_mISDNport == mISDNport)
4039 /* check out correct id */
4040 PERROR("unhandled message: dinfo=%x is not associated with port-dinfo=%x\n",hh->dinfo,pdss1->p_m_d_l3id);
4049 #endif // stacktomanager
4051 /* NOTE: te mode use iframe_t as header */
4052 int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg)
4059 if (!msg || !mISDNport)
4061 frm = (iframe_t *)msg->data;
4062 PDEBUG(DEBUG_ISDN, "prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
4064 /* find Port object of type ISDN */
4068 if (port->p_type == PORT_TYPE_DSS1_TE_IN || port->p_type == PORT_TYPE_DSS1_TE_OUT)
4070 pdss1 = (class Pdss1 *)port;
4071 /* check out correct stack */
4072 if (pdss1->p_m_mISDNport == mISDNport)
4073 /* check out correct id */
4074 if (frm->dinfo == pdss1->p_m_d_l3id)
4076 /* found port, the message belongs to */
4084 pdss1->message_isdn(frm->prim, frm->dinfo, msg->data);
4089 /* process new cr (before setup indication) */
4090 //printf("prim = 0x%x, looking for 0x%x\n",frm->prim, (CC_NEW_CR | INDICATION));
4091 if (frm->prim == (CC_NEW_CR | INDICATION))
4094 /* creating port object */
4095 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
4096 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_TE_IN, mISDNport, name, NULL, 0, 0)))
4097 FATAL("Cannot create Port instance.\n");
4098 /* l3id will be set from dinfo at message_isdn */
4099 pdss1->message_isdn(frm->prim, frm->dinfo, msg->data);
4104 if (frm->prim == (CC_RELEASE_CR | INDICATION))
4106 PDEBUG(DEBUG_ISDN, "unhandled message from stack: call ref released (l3id=0x%x)\n", frm->dinfo);
4110 PERROR("unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
4116 * sending message that were queued during L1 activation
4117 * or releasing port if link is down
4119 void setup_queue(struct mISDNport *mISDNport, int link)
4123 struct message *message;
4125 if (!mISDNport->ntmode)
4128 /* check all port objects for pending message */
4132 if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
4134 pdss1 = (class Pdss1 *)port;
4135 if (pdss1->p_m_mISDNport == mISDNport)
4137 if (pdss1->p_m_d_queue)
4141 PDEBUG(DEBUG_ISDN, "the L1 became active, so we send queued message for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
4142 /* LAYER 1 is up, so we send */
4143 pdss1->message_setup(pdss1->p_m_d_queue->id_from, pdss1->p_m_d_queue->type, &pdss1->p_m_d_queue->param);
4144 message_free(pdss1->p_m_d_queue);
4145 pdss1->p_m_d_queue = NULL;
4148 PDEBUG(DEBUG_ISDN, "the L1 became NOT active, so we release port for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
4149 message = message_create(pdss1->p_serial, pdss1->p_m_d_queue->id_from, PORT_TO_EPOINT, MESSAGE_RELEASE);
4150 message->param.disconnectinfo.cause = 27;
4151 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
4152 message_put(message);
4153 pdss1->new_state(PORT_STATE_RELEASE);
4154 pdss1->p_m_delete = 1;