1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
15 //#include <sys/socket.h>
18 #include <mISDN/q931.h>
19 #include <mISDN/suppserv.h>
21 extern unsigned int mt_assign_pid;
26 static int delete_event(struct lcr_work *work, void *instance, int index);
31 Pdss1::Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
33 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
34 p_m_d_ntmode = mISDNport->ntmode;
35 p_m_d_tespecial = mISDNport->tespecial;
37 memset(&p_m_d_delete, 0, sizeof(p_m_d_delete));
38 add_work(&p_m_d_delete, delete_event, this, 0);
40 p_m_d_queue[0] = '\0';
41 p_m_d_notify_pending = NULL;
42 p_m_d_collect_cause = 0;
43 p_m_d_collect_location = 0;
45 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, %s%s port #%d\n", portname, mISDNport->use, (mISDNport->ntmode)?"NT":"TE", (mISDNport->tespecial)?" (special)":"", p_m_portnum);
54 del_work(&p_m_d_delete);
56 /* remove queued message */
57 if (p_m_d_notify_pending)
58 message_free(p_m_d_notify_pending);
63 * create layer 3 message
65 static struct l3_msg *create_l3msg(void)
73 FATAL("Cannot allocate memory, system overloaded.\n");
74 exit(0); // make gcc happy
78 * if we received a first reply to the setup message,
79 * we will check if we have now channel information
80 * return: <0: error, call is released, -cause is given
81 * 0: ok, nothing to do
83 int Pdss1::received_first_reply_to_setup(unsigned int cmd, int channel, int exclusive)
88 /* correct exclusive to 0, if no explicit channel was given */
89 if (exclusive<0 || channel<=0)
93 if (p_m_b_channel && p_m_b_exclusive) {
94 /*** we gave an exclusive channel (or if we are done) ***/
96 /* if not first reply, we are done */
97 if (p_state != PORT_STATE_OUT_SETUP)
100 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
101 add_trace("channel", "request", "%d (forced)", p_m_b_channel);
102 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
104 /* if give channel not accepted or not equal */
105 if (channel!=-1 && p_m_b_channel!=channel) {
106 add_trace("conclusion", NULL, "forced channel not accepted");
112 add_trace("conclusion", NULL, "channel was accepted");
113 add_trace("connect", "channel", "%d", p_m_b_channel);
116 /* activate our exclusive channel */
117 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
120 /*** we gave a non-exclusive channel ***/
122 /* if not first reply, we are done */
123 if (p_state != PORT_STATE_OUT_SETUP)
126 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
127 add_trace("channel", "request", "%d (suggest)", p_m_b_channel);
128 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
130 /* if channel was accepted as given */
131 if (channel==-1 || p_m_b_channel==channel) {
132 add_trace("conclusion", NULL, "channel was accepted as given");
133 add_trace("connect", "channel", "%d", p_m_b_channel);
135 p_m_b_exclusive = 1; // we are done
136 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
140 /* if channel value is faulty */
142 add_trace("conclusion", NULL, "illegal reply");
144 ret = -111; // protocol error
148 /* if channel was not accepted, try to get it */
149 ret = seize_bchannel(channel, 1); // exclusively
150 add_trace("channel", "available", ret<0?"no":"yes");
152 add_trace("conclusion", NULL, "replied channel not available");
156 add_trace("conclusion", NULL, "replied channel accepted");
157 add_trace("connect", "channel", "%d", p_m_b_channel);
160 /* activate channel given by remote */
161 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
164 /*** we sent 'any channel acceptable' ***/
166 /* if not first reply, we are done */
167 if (p_state != PORT_STATE_OUT_SETUP)
170 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
171 add_trace("channel", "request", "any");
172 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
173 /* if no channel was replied */
175 add_trace("conclusion", NULL, "no channel, protocol error");
177 ret = -111; // protocol error
181 /* we will see, if our received channel is available */
182 ret = seize_bchannel(channel, 1); // exclusively
183 add_trace("channel", "available", ret<0?"no":"yes");
185 add_trace("conclusion", NULL, "replied channel not available");
189 add_trace("conclusion", NULL, "replied channel accepted");
190 add_trace("connect", "channel", "%d", p_m_b_channel);
193 /* activate channel given by remote */
194 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
196 /*** we sent 'no channel available' ***/
198 /* if not the first reply, but a connect, we are forced */
199 if (cmd==MT_CONNECT && p_state!=PORT_STATE_OUT_SETUP) {
200 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (connect)", DIRECTION_NONE);
201 add_trace("channel", "request", "no-channel");
202 add_trace("channel", "reply", (channel>=0)?"%d%s":"(none)", channel, exclusive?" (forced)":"");
204 goto use_from_connect;
206 ret = seize_bchannel(CHANNEL_ANY, 0); // any channel
207 add_trace("channel", "available", ret<0?"no":"yes");
209 add_trace("conclusion", NULL, "no channel available during call-waiting");
213 add_trace("conclusion", NULL, "using channel %d", p_m_b_channel);
214 add_trace("connect", "channel", "%d", p_m_b_channel);
216 p_m_b_exclusive = 1; // we are done
218 /* activate channel given by remote */
219 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
223 /* if not first reply, we are done */
224 if (p_state != PORT_STATE_OUT_SETUP)
227 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (first reply to setup)", DIRECTION_NONE);
228 add_trace("channel", "request", "no-channel");
229 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
230 /* if first reply has no channel, we are done */
232 add_trace("conclusion", NULL, "no channel until connect");
237 /* we will see, if our received channel is available */
239 ret = seize_bchannel(channel, exclusive);
240 add_trace("channel", "available", ret<0?"no":"yes");
242 add_trace("conclusion", NULL, "replied channel not available");
246 add_trace("conclusion", NULL, "replied channel accepted");
247 add_trace("connect", "channel", "%d", p_m_b_channel);
249 p_m_b_exclusive = 1; // we are done
251 /* activate channel given by remote */
252 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
258 * NOTE: we send MT_RELEASE_COMPLETE to "REJECT" the channel
259 * in response to the setup reply
261 l3m = create_l3msg();
262 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
263 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
265 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
266 new_state(PORT_STATE_RELEASE);
267 trigger_work(&p_m_d_delete);
268 return(-34); /* to epoint: no channel available */
273 * hunt bchannel for incoming setup or retrieve or resume
275 int Pdss1::hunt_bchannel(int channel, int exclusive)
277 struct select_channel *selchannel;
278 struct interface_port *ifport = p_m_mISDNport->ifport;
281 chan_trace_header(p_m_mISDNport, this, "CHANNEL SELECTION (setup)", DIRECTION_NONE);
284 if (channel == CHANNEL_NO)
285 add_trace("channel", "request", "no-channel");
287 add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":"");
288 if (channel==CHANNEL_NO && p_type==PORT_TYPE_DSS1_TE_IN) {
289 add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode");
291 return(-6); // channel unacceptable
293 if (channel <= 0) /* not given, no channel, whatever.. */
294 channel = CHANNEL_ANY; /* any channel */
295 add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved);
296 if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) { // of out chan..
297 add_trace("conclusion", NULL, "all channels are reserved");
299 return(-34); // no channel
301 if (channel == CHANNEL_ANY)
304 /* check for given channel in selection list */
305 selchannel = ifport->in_channel;
307 if (selchannel->channel == channel || selchannel->channel == CHANNEL_FREE)
309 selchannel = selchannel->next;
314 /* exclusive channel requests must be in the list */
316 /* no exclusive channel */
318 add_trace("conclusion", NULL, "exclusively requested channel not in list");
320 return(-6); // channel unacceptable
322 /* get index for channel */
323 i = channel-1-(channel>=17);
324 if (i < 0 || i >= p_m_mISDNport->b_num || channel == 16) {
325 add_trace("conclusion", NULL, "exclusively requested channel outside interface range");
327 return(-6); // channel unacceptable
330 if (p_m_mISDNport->b_port[i] == NULL)
332 add_trace("conclusion", NULL, "exclusively requested channel is busy");
334 return(-6); // channel unacceptable
337 /* requested channels in list will be used */
339 /* get index for channel */
340 i = channel-1-(channel>=17);
341 if (i < 0 || i >= p_m_mISDNport->b_num || channel == 16) {
342 add_trace("info", NULL, "requested channel %d outside interface range", channel);
343 } else /* if inside range (else) check if available */
344 if (p_m_mISDNport->b_port[i] == NULL)
348 /* if channel is not available or not in list, it must be searched */
350 /* check for first free channel in list */
352 selchannel = ifport->in_channel;
354 switch(selchannel->channel) {
355 case CHANNEL_FREE: /* free channel */
356 add_trace("hunting", "channel", "free");
357 if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num)
358 break; /* all channel in use or reserverd */
361 while(i < p_m_mISDNport->b_num) {
362 if (p_m_mISDNport->b_port[i] == NULL) {
363 channel = i+1+(i>=15);
371 add_trace("hunting", "channel", "%d", selchannel->channel);
372 if (selchannel->channel<1 || selchannel->channel==16)
373 break; /* invalid channels */
374 i = selchannel->channel-1-(selchannel->channel>=17);
375 if (i >= p_m_mISDNport->b_num)
376 break; /* channel not in port */
377 if (p_m_mISDNport->b_port[i] == NULL) {
378 channel = selchannel->channel;
384 break; /* found channel */
385 selchannel = selchannel->next;
388 add_trace("conclusion", NULL, "no channel available");
390 return(-6); // channel unacceptable
394 add_trace("conclusion", NULL, "channel available");
395 add_trace("connect", "channel", "%d", channel);
401 * handles all indications
403 /* CC_SETUP INDICATION */
404 void Pdss1::setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
406 int calling_type, calling_plan, calling_present, calling_screen;
407 int calling_type2, calling_plan2, calling_present2, calling_screen2;
408 int called_type, called_plan;
409 int redir_type, redir_plan, redir_present, redir_screen, redir_reason;
410 int hlc_coding, hlc_presentation, hlc_interpretation, hlc_hlc, hlc_exthlc;
411 int bearer_coding, bearer_capability, bearer_mode, bearer_rate, bearer_multi, bearer_user;
412 int exclusive, channel;
414 unsigned char keypad[33] = "";
415 unsigned char useruser[128];
416 int useruser_len = 0, useruser_protocol;
417 class Endpoint *epoint;
418 struct lcr_msg *message;
420 /* process given callref */
421 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_IND, DIRECTION_IN);
422 add_trace("callref", "new", "0x%x", pid);
424 /* release in case the ID is already in use */
425 add_trace("error", NULL, "callref already in use");
427 l3m = create_l3msg();
428 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
429 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47);
430 add_trace("reason", NULL, "callref already in use");
432 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, pid, l3m);
433 new_state(PORT_STATE_RELEASE);
434 trigger_work(&p_m_d_delete);
438 p_m_d_ces = pid >> 16;
441 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_IND, DIRECTION_IN);
442 dec_ie_calling_pn(l3m, &calling_type, &calling_plan, &calling_present, &calling_screen, (unsigned char *)p_callerinfo.id, sizeof(p_callerinfo.id), &calling_type2, &calling_plan2, &calling_present2, &calling_screen2, (unsigned char *)p_callerinfo.id2, sizeof(p_callerinfo.id2));
443 dec_ie_called_pn(l3m, &called_type, &called_plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
444 dec_ie_keypad(l3m, (unsigned char *)keypad, sizeof(keypad));
445 /* te-mode: CNIP (calling name identification presentation) */
446 dec_facility_centrex(l3m, (unsigned char *)p_callerinfo.name, sizeof(p_callerinfo.name));
447 dec_ie_useruser(l3m, &useruser_protocol, useruser, &useruser_len);
448 dec_ie_complete(l3m, &p_dialinginfo.sending_complete);
449 dec_ie_redir_nr(l3m, &redir_type, &redir_plan, &redir_present, &redir_screen, &redir_reason, (unsigned char *)p_redirinfo.id, sizeof(p_redirinfo.id));
450 dec_ie_channel_id(l3m, &exclusive, &channel);
451 dec_ie_hlc(l3m, &hlc_coding, &hlc_interpretation, &hlc_presentation, &hlc_hlc, &hlc_exthlc);
452 dec_ie_bearer(l3m, &bearer_coding, &bearer_capability, &bearer_mode, &bearer_rate, &bearer_multi, &bearer_user);
453 dec_ie_display(l3m, (unsigned char *)p_dialinginfo.display, sizeof(p_dialinginfo.display));
456 /* if blocked, release call with MT_RELEASE_COMPLETE */
457 if (p_m_mISDNport->ifport->block) {
458 l3m = create_l3msg();
459 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
460 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 27); /* temporary unavailable */
461 add_trace("reason", NULL, "port blocked");
463 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
464 new_state(PORT_STATE_RELEASE);
465 trigger_work(&p_m_d_delete);
470 switch (calling_present) {
472 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
475 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
478 p_callerinfo.present = INFO_PRESENT_ALLOWED;
481 switch (calling_screen) {
483 p_callerinfo.screen = INFO_SCREEN_USER;
486 p_callerinfo.screen = INFO_SCREEN_USER_VERIFIED_PASSED;
489 p_callerinfo.screen = INFO_SCREEN_USER_VERIFIED_FAILED;
492 p_callerinfo.screen = INFO_SCREEN_NETWORK;
495 switch (calling_type) {
497 p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
500 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
503 p_callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
506 p_callerinfo.ntype = INFO_NTYPE_NATIONAL;
509 p_callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
512 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
515 p_callerinfo.isdn_port = p_m_portnum;
516 SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
519 switch (calling_present2) {
521 p_callerinfo.present2 = INFO_PRESENT_RESTRICTED;
524 p_callerinfo.present2 = INFO_PRESENT_NOTAVAIL;
527 p_callerinfo.present2 = INFO_PRESENT_ALLOWED;
530 switch (calling_screen2) {
532 p_callerinfo.screen2 = INFO_SCREEN_USER;
535 p_callerinfo.screen2 = INFO_SCREEN_USER_VERIFIED_PASSED;
538 p_callerinfo.screen2 = INFO_SCREEN_USER_VERIFIED_FAILED;
541 p_callerinfo.screen2 = INFO_SCREEN_NETWORK;
544 switch (calling_type2) {
546 p_callerinfo.ntype2 = INFO_NTYPE_NOTPRESENT;
549 p_callerinfo.ntype2 = INFO_NTYPE_UNKNOWN;
552 p_callerinfo.ntype2 = INFO_NTYPE_INTERNATIONAL;
555 p_callerinfo.ntype2 = INFO_NTYPE_NATIONAL;
558 p_callerinfo.ntype2 = INFO_NTYPE_SUBSCRIBER;
561 p_callerinfo.ntype2 = INFO_NTYPE_UNKNOWN;
565 /* dialing information */
566 SCAT(p_dialinginfo.id, (char *)keypad);
567 switch (called_type) {
569 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
572 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
575 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
578 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
583 switch (redir_present) {
585 p_redirinfo.present = INFO_PRESENT_RESTRICTED;
588 p_redirinfo.present = INFO_PRESENT_NOTAVAIL;
591 p_redirinfo.present = INFO_PRESENT_ALLOWED;
594 switch (redir_screen) {
596 p_redirinfo.screen = INFO_SCREEN_USER;
599 p_redirinfo.screen = INFO_SCREEN_USER_VERIFIED_PASSED;
602 p_redirinfo.screen = INFO_SCREEN_USER_VERIFIED_FAILED;
605 p_redirinfo.screen = INFO_SCREEN_NETWORK;
608 switch (redir_reason) {
610 p_redirinfo.reason = INFO_REDIR_BUSY;
613 p_redirinfo.reason = INFO_REDIR_NORESPONSE;
616 p_redirinfo.reason = INFO_REDIR_UNCONDITIONAL;
619 p_redirinfo.reason = INFO_REDIR_CALLDEFLECT;
622 p_redirinfo.reason = INFO_REDIR_OUTOFORDER;
625 p_redirinfo.reason = INFO_REDIR_UNKNOWN;
628 switch (redir_type) {
630 p_redirinfo.ntype = INFO_NTYPE_NOTPRESENT;
633 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
636 p_redirinfo.ntype = INFO_NTYPE_INTERNATIONAL;
639 p_redirinfo.ntype = INFO_NTYPE_NATIONAL;
642 p_redirinfo.ntype = INFO_NTYPE_SUBSCRIBER;
645 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
648 p_redirinfo.isdn_port = p_m_portnum;
650 /* bearer capability */
651 switch (bearer_capability) {
653 p_capainfo.bearer_capa = INFO_BC_AUDIO;
654 bearer_user = (options.law=='a')?3:2;
657 p_capainfo.bearer_capa = bearer_capability;
660 switch (bearer_mode) {
662 p_capainfo.bearer_mode = INFO_BMODE_PACKET;
665 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
668 switch (bearer_user) {
670 p_capainfo.bearer_info1 = INFO_INFO1_NONE;
673 p_capainfo.bearer_info1 = bearer_user + 0x80;
680 p_capainfo.hlc = INFO_HLC_NONE;
683 p_capainfo.hlc = hlc_hlc + 0x80;
686 switch (hlc_exthlc) {
688 p_capainfo.exthlc = INFO_HLC_NONE;
691 p_capainfo.exthlc = hlc_exthlc + 0x80;
695 /* set bchannel mode */
696 if (p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED
697 || p_capainfo.bearer_capa==INFO_BC_DATARESTRICTED
698 || p_capainfo.bearer_capa==INFO_BC_VIDEO)
699 p_capainfo.source_mode = B_MODE_HDLC;
701 p_capainfo.source_mode = B_MODE_TRANSPARENT;
702 p_m_b_mode = p_capainfo.source_mode;
705 ret = channel = hunt_bchannel(channel, exclusive);
710 ret = seize_bchannel(channel, 1);
714 * NOTE: we send MT_RELEASE_COMPLETE to "REJECT" the channel
715 * in response to the setup
717 l3m = create_l3msg();
718 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
719 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
721 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
722 new_state(PORT_STATE_RELEASE);
723 trigger_work(&p_m_d_delete);
726 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
728 /* create endpoint */
730 FATAL("Incoming call but already got an endpoint.\n");
731 if (!(epoint = new Endpoint(p_serial, 0)))
732 FATAL("No memory for Endpoint instance\n");
733 epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
734 epointlist_new(epoint->ep_serial);
736 /* send setup message to endpoit */
737 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
738 message->param.setup.isdn_port = p_m_portnum;
739 message->param.setup.port_type = p_type;
740 // message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
741 memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
742 memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
743 memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
744 memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
745 memcpy(message->param.setup.useruser.data, &useruser, useruser_len);
746 message->param.setup.useruser.len = useruser_len;
747 message->param.setup.useruser.protocol = useruser_protocol;
748 message_put(message);
750 new_state(PORT_STATE_IN_SETUP);
753 /* CC_INFORMATION INDICATION */
754 void Pdss1::information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
757 unsigned char keypad[33] = "", display[128] = "";
758 struct lcr_msg *message;
760 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_IND, DIRECTION_IN);
761 dec_ie_called_pn(l3m, &type, &plan, (unsigned char *)p_dialinginfo.id, sizeof(p_dialinginfo.id));
762 dec_ie_keypad(l3m, (unsigned char *)keypad, sizeof(keypad));
763 dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
764 dec_ie_complete(l3m, &p_dialinginfo.sending_complete);
767 SCAT(p_dialinginfo.id, (char *)keypad);
770 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
773 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
776 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
779 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
782 SCPY(p_dialinginfo.display, (char *)display);
783 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
784 memcpy(&message->param.information, &p_dialinginfo, sizeof(struct dialing_info));
785 message_put(message);
786 /* reset overlap timeout */
790 /* CC_SETUP_ACCNOWLEDGE INDICATION */
791 void Pdss1::setup_acknowledge_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
793 int exclusive, channel;
794 int coding, location, progress;
796 struct lcr_msg *message;
797 int max = p_m_mISDNport->ifport->dialmax;
801 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_IND, DIRECTION_IN);
802 dec_ie_channel_id(l3m, &exclusive, &channel);
803 dec_ie_progress(l3m, &coding, &location, &progress);
807 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
808 message->param.progressinfo.progress = progress;
809 message->param.progressinfo.location = location;
810 message_put(message);
813 /* process channel */
814 ret = received_first_reply_to_setup(cmd, channel, exclusive);
816 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
817 message->param.disconnectinfo.cause = -ret;
818 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
819 message_put(message);
820 new_state(PORT_STATE_RELEASE);
821 trigger_work(&p_m_d_delete);
825 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_OVERLAP);
826 message_put(message);
828 new_state(PORT_STATE_OUT_OVERLAP);
830 number = p_m_d_queue;
831 while (number[0]) { /* as long we have something to dial */
832 if (max > (int)strlen(number) || max == 0)
833 max = (int)strlen(number);
835 nl3m = create_l3msg();
836 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
837 enc_ie_called_pn(nl3m, 0, 1, (unsigned char *)number, max);
839 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, nl3m);
842 p_m_d_queue[0] = '\0';
845 /* CC_PROCEEDING INDICATION */
846 void Pdss1::proceeding_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
848 int exclusive, channel;
849 int coding, location, progress;
851 struct lcr_msg *message;
852 int notify = -1, type, plan, present;
855 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_IND, DIRECTION_IN);
856 dec_ie_channel_id(l3m, &exclusive, &channel);
857 dec_ie_progress(l3m, &coding, &location, &progress);
858 dec_ie_notify(l3m, ¬ify);
859 dec_ie_redir_dn(l3m, &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
863 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
864 message->param.progressinfo.progress = progress;
865 message->param.progressinfo.location = location;
866 message_put(message);
869 ret = received_first_reply_to_setup(cmd, channel, exclusive);
871 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
872 message->param.disconnectinfo.cause = -ret;
873 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
874 message_put(message);
875 new_state(PORT_STATE_RELEASE);
876 trigger_work(&p_m_d_delete);
879 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
880 message_put(message);
882 new_state(PORT_STATE_OUT_PROCEEDING);
888 if (type >= 0 || notify) {
889 if (!notify && type >= 0)
891 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
892 message->param.notifyinfo.notify = notify;
893 SCPY(message->param.notifyinfo.id, redir);
894 /* redirection number */
897 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
900 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
903 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
908 message->param.notifyinfo.ntype = INFO_NTYPE_NOTPRESENT;
911 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
914 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
917 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
920 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
923 message->param.notifyinfo.isdn_port = p_m_portnum;
924 message_put(message);
928 /* CC_ALERTING INDICATION */
929 void Pdss1::alerting_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
931 int exclusive, channel;
932 int coding, location, progress;
934 struct lcr_msg *message;
935 int notify = -1, type, plan, present;
938 l1l2l3_trace_header(p_m_mISDNport, this, L3_ALERTING_IND, DIRECTION_IN);
939 dec_ie_channel_id(l3m, &exclusive, &channel);
940 dec_ie_progress(l3m, &coding, &location, &progress);
941 dec_ie_notify(l3m, ¬ify);
942 dec_ie_redir_dn(l3m, &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
946 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
947 message->param.progressinfo.progress = progress;
948 message->param.progressinfo.location = location;
949 message_put(message);
952 /* process channel */
953 ret = received_first_reply_to_setup(cmd, channel, exclusive);
955 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
956 message->param.disconnectinfo.cause = -ret;
957 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
958 message_put(message);
959 new_state(PORT_STATE_RELEASE);
960 trigger_work(&p_m_d_delete);
963 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
964 message_put(message);
966 new_state(PORT_STATE_OUT_ALERTING);
972 if (type >= 0 || notify) {
973 if (!notify && type >= 0)
975 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
976 message->param.notifyinfo.notify = notify;
977 SCPY(message->param.notifyinfo.id, redir);
980 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
983 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
986 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
991 message->param.notifyinfo.ntype = INFO_NTYPE_NOTPRESENT;
994 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
997 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1000 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1003 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1006 message->param.notifyinfo.isdn_port = p_m_portnum;
1007 message_put(message);
1011 /* CC_CONNECT INDICATION */
1012 void Pdss1::connect_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1014 int exclusive, channel;
1015 int type, plan, present, screen;
1017 struct lcr_msg *message;
1018 int bchannel_before;
1020 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_IND, DIRECTION_IN);
1021 dec_ie_channel_id(l3m, &exclusive, &channel);
1022 dec_ie_connected_pn(l3m, &type, &plan, &present, &screen, (unsigned char *)p_connectinfo.id, sizeof(p_connectinfo.id));
1023 dec_ie_display(l3m, (unsigned char *)p_connectinfo.display, sizeof(p_connectinfo.display));
1024 /* te-mode: CONP (connected name identification presentation) */
1025 dec_facility_centrex(l3m, (unsigned char *)p_connectinfo.name, sizeof(p_connectinfo.name));
1028 /* select channel */
1029 bchannel_before = p_m_b_channel;
1030 ret = received_first_reply_to_setup(cmd, channel, exclusive);
1032 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1033 message->param.disconnectinfo.cause = -ret;
1034 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1035 message_put(message);
1036 new_state(PORT_STATE_RELEASE);
1037 trigger_work(&p_m_d_delete);
1041 /* connect information */
1044 p_connectinfo.present = INFO_PRESENT_RESTRICTED;
1047 p_connectinfo.present = INFO_PRESENT_NOTAVAIL;
1050 p_connectinfo.present = INFO_PRESENT_ALLOWED;
1055 p_connectinfo.screen = INFO_SCREEN_USER;
1058 p_connectinfo.screen = INFO_SCREEN_USER_VERIFIED_PASSED;
1061 p_connectinfo.screen = INFO_SCREEN_USER_VERIFIED_FAILED;
1064 p_connectinfo.screen = INFO_SCREEN_NETWORK;
1069 p_connectinfo.ntype = INFO_NTYPE_NOTPRESENT;
1072 p_connectinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1075 p_connectinfo.ntype = INFO_NTYPE_NATIONAL;
1078 p_connectinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1081 p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1084 p_connectinfo.isdn_port = p_m_portnum;
1085 SCPY(p_connectinfo.interface, p_m_mISDNport->ifport->interface->name);
1087 /* only in nt-mode we send connect ack. in te-mode it is done by stack itself or optional */
1089 /* send connect acknowledge */
1090 l3m = create_l3msg();
1091 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_RES, DIRECTION_OUT);
1092 /* if we had no bchannel before, we send it now */
1093 if (!bchannel_before && p_m_b_channel)
1094 enc_ie_channel_id(l3m, 1, p_m_b_channel);
1096 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CONNECT_ACKNOWLEDGE, p_m_d_l3id, l3m);
1099 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1100 memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
1101 message_put(message);
1103 new_state(PORT_STATE_CONNECT);
1106 /* CC_DISCONNECT INDICATION */
1107 void Pdss1::disconnect_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1109 int location, cause;
1110 int coding, proglocation, progress;
1111 struct lcr_msg *message;
1112 unsigned char display[128] = "";
1114 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_IND, DIRECTION_IN);
1115 dec_ie_progress(l3m, &coding, &proglocation, &progress);
1116 dec_ie_cause(l3m, &location, &cause);
1117 dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
1122 location = LOCATION_PRIVATE_LOCAL;
1125 if (progress >= 0) {
1126 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
1127 message->param.progressinfo.progress = progress;
1128 message->param.progressinfo.location = proglocation;
1129 message_put(message);
1132 /* release if remote sends us no tones */
1133 if (!p_m_mISDNport->earlyb) {
1136 l3m = create_l3msg();
1137 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
1138 enc_ie_cause(l3m, location, cause); /* normal */
1139 add_trace("reason", NULL, "no remote patterns");
1141 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
1143 /* sending release to endpoint */
1144 if (location == LOCATION_PRIVATE_LOCAL)
1145 location = LOCATION_PRIVATE_REMOTE;
1146 while(p_epointlist) {
1147 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1148 message->param.disconnectinfo.cause = cause;
1149 message->param.disconnectinfo.location = location;
1150 SCAT(message->param.disconnectinfo.display, (char *)display);
1151 message_put(message);
1153 free_epointlist(p_epointlist);
1155 new_state(PORT_STATE_RELEASE);
1156 trigger_work(&p_m_d_delete);
1160 /* sending disconnect to active endpoint and release to inactive endpoints */
1161 if (location == LOCATION_PRIVATE_LOCAL)
1162 location = LOCATION_PRIVATE_REMOTE;
1163 if (ACTIVE_EPOINT(p_epointlist)) {
1164 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1165 message->param.disconnectinfo.location = location;
1166 message->param.disconnectinfo.cause = cause;
1167 SCAT(message->param.disconnectinfo.display, (char *)display);
1168 message_put(message);
1170 while(INACTIVE_EPOINT(p_epointlist)) {
1171 message = message_create(p_serial, INACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1172 message->param.disconnectinfo.location = location;
1173 message->param.disconnectinfo.cause = cause;
1174 SCAT(message->param.disconnectinfo.display, (char *)display);
1175 message_put(message);
1177 free_epointid(INACTIVE_EPOINT(p_epointlist));
1179 new_state(PORT_STATE_IN_DISCONNECT);
1182 /* CC_DISCONNECT INDICATION */
1183 void Pdss1::disconnect_ind_i(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1185 int location, cause;
1188 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_IND, DIRECTION_IN);
1189 if (p_m_d_collect_cause > 0) {
1190 add_trace("old-cause", "location", "%d", p_m_d_collect_location);
1191 add_trace("old-cause", "value", "%d", p_m_d_collect_cause);
1193 dec_ie_cause(l3m, &location, &cause);
1194 if (location == LOCATION_PRIVATE_LOCAL)
1195 location = LOCATION_PRIVATE_REMOTE;
1198 collect_cause(&p_m_d_collect_cause, &p_m_d_collect_location, cause, location);
1199 add_trace("new-cause", "location", "%d", p_m_d_collect_location);
1200 add_trace("new-cause", "value", "%d", p_m_d_collect_cause);
1205 /* CC_RELEASE INDICATION */
1206 void Pdss1::release_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1208 int location, cause;
1209 struct lcr_msg *message;
1210 unsigned char display[128] = "";
1212 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_IND, DIRECTION_IN);
1213 dec_ie_cause(l3m, &location, &cause);
1214 dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
1219 location = LOCATION_PRIVATE_LOCAL;
1222 /* sending release to endpoint */
1223 if (location == LOCATION_PRIVATE_LOCAL)
1224 location = LOCATION_PRIVATE_REMOTE;
1225 while(p_epointlist) {
1226 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1227 message->param.disconnectinfo.cause = cause;
1228 message->param.disconnectinfo.location = location;
1229 SCAT(message->param.disconnectinfo.display, (char *)display);
1230 message_put(message);
1232 free_epointlist(p_epointlist);
1235 new_state(PORT_STATE_RELEASE);
1236 trigger_work(&p_m_d_delete);
1239 /* CC_RESTART INDICATION */
1240 void Pdss1::restart_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1242 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESTART_IND, DIRECTION_IN);
1245 // L3 process is not toucht. (not even by network stack)
1248 /* CC_RELEASE_COMPLETE INDICATION (a reject) */
1249 void Pdss1::release_complete_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1251 int location, cause;
1252 struct lcr_msg *message;
1254 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_IND, DIRECTION_IN);
1255 /* in case layer 2 is down during setup, we send cause 27 loc 5 */
1256 if (p_state == PORT_STATE_OUT_SETUP && p_m_mISDNport->l1link == 0) {
1260 dec_ie_cause(l3m, &location, &cause);
1261 if (p_m_mISDNport->l1link < 0)
1262 add_trace("layer 1", NULL, "unknown");
1264 add_trace("layer 1", NULL, (p_m_mISDNport->l1link)?"up":"down");
1267 if (location == LOCATION_PRIVATE_LOCAL)
1268 location = LOCATION_PRIVATE_REMOTE;
1272 location = LOCATION_PRIVATE_LOCAL;
1275 /* sending release to endpoint */
1276 while(p_epointlist) {
1277 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1278 message->param.disconnectinfo.cause = cause;
1279 message->param.disconnectinfo.location = location;
1280 message_put(message);
1282 free_epointlist(p_epointlist);
1285 new_state(PORT_STATE_RELEASE);
1286 trigger_work(&p_m_d_delete);
1290 void Pdss1::t312_timeout_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1292 // not required, release is performed with MT_FREE
1295 /* CC_NOTIFY INDICATION */
1296 void Pdss1::notify_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1298 struct lcr_msg *message;
1299 int notify, type, plan, present;
1300 unsigned char notifyid[sizeof(message->param.notifyinfo.id)];
1301 unsigned char display[128] = "";
1303 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_IND, DIRECTION_IN);
1304 dec_ie_notify(l3m, ¬ify);
1305 dec_ie_redir_dn(l3m, &type, &plan, &present, notifyid, sizeof(notifyid));
1306 dec_ie_display(l3m, (unsigned char *)display, sizeof(display));
1309 if (!ACTIVE_EPOINT(p_epointlist))
1311 /* notification indicator */
1315 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1316 message->param.notifyinfo.notify = notify;
1317 SCPY(message->param.notifyinfo.id, (char *)notifyid);
1318 /* redirection number */
1321 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1324 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1327 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1332 message->param.notifyinfo.ntype = INFO_NTYPE_NOTPRESENT;
1335 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1338 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1341 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1344 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1347 SCAT(message->param.notifyinfo.display, (char *)display);
1348 message->param.notifyinfo.isdn_port = p_m_portnum;
1349 message_put(message);
1353 /* CC_HOLD INDICATION */
1354 struct lcr_msg *message;
1355 void Pdss1::hold_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1357 // class Endpoint *epoint;
1359 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_IND, DIRECTION_IN);
1362 if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold) {
1363 l3m = create_l3msg();
1364 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_REJECT_REQ, DIRECTION_OUT);
1365 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
1366 add_trace("reason", NULL, "no endpoint");
1368 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_HOLD_REJECT, p_m_d_l3id, l3m);
1373 /* notify the hold of call */
1374 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1375 message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1376 message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1377 message_put(message);
1379 /* deactivate bchannel */
1380 chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (hold)", DIRECTION_NONE);
1381 add_trace("disconnect", "channel", "%d", p_m_b_channel);
1385 /* set hold state */
1388 epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
1389 if (epoint && p_m_d_ntmode) {
1390 if (p_settings.tout_hold)
1391 schedule_timer(&p_m_timeout, p_settings.tout_hold, 0);
1395 /* acknowledge hold */
1396 l3m = create_l3msg();
1397 l1l2l3_trace_header(p_m_mISDNport, this, L3_HOLD_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1399 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_HOLD_ACKNOWLEDGE, p_m_d_l3id, l3m);
1403 /* CC_RETRIEVE INDICATION */
1404 void Pdss1::retrieve_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1406 struct lcr_msg *message;
1407 int channel, exclusive, cause;
1410 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_IND, DIRECTION_IN);
1411 dec_ie_channel_id(l3m, &exclusive, &channel);
1415 cause = 101; /* incompatible state */
1418 l3m = create_l3msg();
1419 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_REJECT_REQ, DIRECTION_OUT);
1420 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, cause);
1422 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RETRIEVE_REJECT, p_m_d_l3id, l3m);
1427 /* notify the retrieve of call */
1428 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1429 message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1430 message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
1431 message_put(message);
1434 ret = channel = hunt_bchannel(channel, exclusive);
1439 ret = seize_bchannel(channel, 1);
1445 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
1447 /* set hold state */
1449 unsched_timer(&p_m_timeout);
1451 /* acknowledge retrieve */
1452 l3m = create_l3msg();
1453 l1l2l3_trace_header(p_m_mISDNport, this, L3_RETRIEVE_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1454 enc_ie_channel_id(l3m, 1, p_m_b_channel);
1456 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RETRIEVE_ACKNOWLEDGE, p_m_d_l3id, l3m);
1459 /* CC_SUSPEND INDICATION */
1460 void Pdss1::suspend_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1462 struct lcr_msg *message;
1463 class Endpoint *epoint;
1464 unsigned char callid[8];
1466 int ret = -31; /* normal, unspecified */
1468 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_IND, DIRECTION_IN);
1469 dec_ie_call_id(l3m, callid, &len);
1472 if (!ACTIVE_EPOINT(p_epointlist)) {
1474 l3m = create_l3msg();
1475 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_REJECT_REQ, DIRECTION_OUT);
1476 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1478 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SUSPEND_REJECT, p_m_d_l3id, l3m);
1485 /* check if call id is in use */
1486 epoint = epoint_first;
1488 if (epoint->ep_park) {
1489 if (epoint->ep_park_len == len)
1490 if (!memcmp(epoint->ep_park_callid, callid, len)) {
1491 ret = -84; /* call id in use */
1495 epoint = epoint->next;
1498 /* notify the hold of call */
1499 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1500 message->param.notifyinfo.notify = INFO_NOTIFY_USER_SUSPENDED;
1501 message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1502 message_put(message);
1504 /* deactivate bchannel */
1505 chan_trace_header(p_m_mISDNport, this, "CHANNEL RELEASE (suspend)", DIRECTION_NONE);
1506 add_trace("disconnect", "channel", "%d", p_m_b_channel);
1510 /* sending suspend to endpoint */
1511 while (p_epointlist) {
1512 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_SUSPEND);
1513 memcpy(message->param.parkinfo.callid, callid, sizeof(message->param.parkinfo.callid));
1514 message->param.parkinfo.len = len;
1515 message_put(message);
1517 free_epointlist(p_epointlist);
1520 /* sending SUSPEND_ACKNOWLEDGE */
1521 l3m = create_l3msg();
1522 l1l2l3_trace_header(p_m_mISDNport, this, L3_SUSPEND_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1524 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SUSPEND_ACKNOWLEDGE, p_m_d_l3id, l3m);
1526 new_state(PORT_STATE_RELEASE);
1527 trigger_work(&p_m_d_delete);
1530 /* CC_RESUME INDICATION */
1531 void Pdss1::resume_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1533 unsigned char callid[8];
1535 int channel, exclusive;
1536 class Endpoint *epoint;
1537 struct lcr_msg *message;
1540 /* process given callref */
1541 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_IND, DIRECTION_IN);
1542 add_trace("callref", "new", "0x%x", pid);
1544 /* release is case the ID is already in use */
1545 add_trace("error", NULL, "callref already in use");
1547 l3m = create_l3msg();
1548 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_REJECT_REQ, DIRECTION_OUT);
1549 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47);
1550 add_trace("reason", NULL, "callref already in use");
1552 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RESUME_REJECT, pid, l3m);
1553 new_state(PORT_STATE_RELEASE);
1554 trigger_work(&p_m_d_delete);
1558 p_m_d_ces = pid >> 16;
1561 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_IND, DIRECTION_IN);
1562 dec_ie_call_id(l3m, callid, &len);
1565 /* if blocked, release call */
1566 if (p_m_mISDNport->ifport->block) {
1574 /* channel_id (no channel is possible in message) */
1576 channel = -1; /* any channel */
1579 ret = channel = hunt_bchannel(channel, exclusive);
1583 // mode (if hdlc parked) to be done. never mind, this is almost never requested
1585 ret = seize_bchannel(channel, 1);
1589 l3m = create_l3msg();
1590 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_REJECT_REQ, DIRECTION_OUT);
1591 enc_ie_cause(l3m, (p_m_mISDNport->locally)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1593 add_trace("reason", NULL, "port blocked");
1595 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RESUME_REJECT, p_m_d_l3id, l3m);
1596 new_state(PORT_STATE_RELEASE);
1597 trigger_work(&p_m_d_delete);
1600 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
1602 /* create endpoint */
1604 FATAL("Incoming resume but already got an endpoint.\n");
1605 ret = -85; /* no call suspended */
1606 epoint = epoint_first;
1608 if (epoint->ep_park) {
1609 ret = -83; /* suspended call exists, but this not */
1610 if (epoint->ep_park_len == len)
1611 if (!memcmp(epoint->ep_park_callid, callid, len))
1614 epoint = epoint->next;
1619 epointlist_new(epoint->ep_serial);
1620 if (!(epoint->portlist_new(p_serial, p_type, p_m_mISDNport->earlyb)))
1621 FATAL("No memory for portlist\n");
1622 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RESUME);
1623 message_put(message);
1625 /* notify the resume of call */
1626 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1627 message->param.notifyinfo.notify = INFO_NOTIFY_USER_RESUMED;
1628 message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
1629 message_put(message);
1631 /* sending RESUME_ACKNOWLEDGE */
1632 l3m = create_l3msg();
1633 l1l2l3_trace_header(p_m_mISDNport, this, L3_RESUME_ACKNOWLEDGE_REQ, DIRECTION_OUT);
1634 enc_ie_channel_id(l3m, 1, p_m_b_channel);
1636 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RESUME_ACKNOWLEDGE, p_m_d_l3id, l3m);
1638 new_state(PORT_STATE_CONNECT);
1642 /* CC_FACILITY INDICATION */
1643 void Pdss1::facility_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1645 unsigned char fac_ie[256];
1646 struct asn1_parm fac;
1648 struct lcr_msg *message;
1650 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_IND, DIRECTION_IN);
1651 dec_ie_facility(l3m, fac_ie + 1, &fac_len);
1652 fac_ie[0] = fac_len;
1659 decodeFac(fac_ie, &fac);
1662 switch(fac.u.inv.operationValue) {
1664 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
1665 message->param.threepty.begin = 1;
1666 message->param.threepty.invoke = 1;
1667 message->param.threepty.invoke_id = fac.u.inv.invokeId;
1668 message_put(message);
1672 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
1673 message->param.threepty.end = 1;
1674 message->param.threepty.invoke = 1;
1675 message->param.threepty.invoke_id = fac.u.inv.invokeId;
1676 message_put(message);
1686 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
1687 message->param.facilityinfo.len = fac_len;
1688 memcpy(message->param.facilityinfo.data, fac_ie, fac_len);
1689 message_put(message);
1693 /* CC_PROGRESS INDICATION */
1694 void Pdss1::progress_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1696 int coding, location, progress;
1698 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROGRESS_IND, DIRECTION_IN);
1699 dec_ie_progress(l3m, &coding, &location, &progress);
1702 if (progress >= 0) {
1703 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
1704 message->param.progressinfo.progress = progress;
1705 message->param.progressinfo.location = location;
1706 message_put(message);
1712 * handler for isdn connections
1713 * incoming information are parsed and sent via message to the endpoint
1715 void Pdss1::message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1722 PERROR("Pdss1(%s) timeout without cause.\n", p_name);
1725 if (l3m->cause[0] != 5) {
1726 PERROR("Pdss1(%s) expecting timeout with timer diagnostic. (got len=%d)\n", p_name, l3m->cause[0]);
1729 timer = (l3m->cause[3]-'0')*100;
1730 timer += (l3m->cause[4]-'0')*10;
1731 timer += (l3m->cause[5]-'0');
1732 l1l2l3_trace_header(p_m_mISDNport, this, L3_TIMEOUT_IND, DIRECTION_IN);
1733 add_trace("timer", NULL, "%d", timer);
1736 t312_timeout_ind(cmd, pid, l3m);
1740 if (p_state != PORT_STATE_IDLE)
1742 setup_ind(cmd, pid, l3m);
1745 case MT_INFORMATION:
1746 information_ind(cmd, pid, l3m);
1749 case MT_SETUP_ACKNOWLEDGE:
1750 if (p_state != PORT_STATE_OUT_SETUP) {
1751 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
1754 setup_acknowledge_ind(cmd, pid, l3m);
1757 case MT_CALL_PROCEEDING:
1758 if (p_state != PORT_STATE_OUT_SETUP
1759 && p_state != PORT_STATE_OUT_OVERLAP) {
1760 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
1763 proceeding_ind(cmd, pid, l3m);
1767 if (p_state != PORT_STATE_OUT_SETUP
1768 && p_state != PORT_STATE_OUT_OVERLAP
1769 && p_state != PORT_STATE_OUT_PROCEEDING) {
1770 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
1773 alerting_ind(cmd, pid, l3m);
1777 if (p_state != PORT_STATE_OUT_SETUP
1778 && p_state != PORT_STATE_OUT_OVERLAP
1779 && p_state != PORT_STATE_OUT_PROCEEDING
1780 && p_state != PORT_STATE_OUT_ALERTING) {
1781 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING.\n", p_name);
1784 connect_ind(cmd, pid, l3m);
1785 if (p_m_d_notify_pending) {
1786 /* send pending notify message during connect */
1787 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
1788 message_free(p_m_d_notify_pending);
1789 p_m_d_notify_pending = NULL;
1793 case MT_CONNECT_ACKNOWLEDGE:
1794 if (p_state == PORT_STATE_CONNECT_WAITING)
1795 new_state(PORT_STATE_CONNECT);
1796 if (p_m_d_notify_pending) {
1797 /* send pending notify message during connect-ack */
1798 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
1799 message_free(p_m_d_notify_pending);
1800 p_m_d_notify_pending = NULL;
1805 disconnect_ind(cmd, pid, l3m);
1809 release_ind(cmd, pid, l3m);
1812 case MT_RELEASE_COMPLETE:
1813 release_complete_ind(cmd, pid, l3m);
1817 restart_ind(cmd, pid, l3m);
1821 notify_ind(cmd, pid, l3m);
1825 hold_ind(cmd, pid, l3m);
1829 retrieve_ind(cmd, pid, l3m);
1833 suspend_ind(cmd, pid, l3m);
1837 resume_ind(cmd, pid, l3m);
1841 facility_ind(cmd, pid, l3m);
1845 progress_ind(cmd, pid, l3m);
1849 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_L3ID_IND, DIRECTION_IN);
1850 add_trace("callref", NULL, "0x%x", p_m_d_l3id);
1853 trigger_work(&p_m_d_delete);
1855 /* sending release to endpoint in case we still have an endpoint
1856 * this is because we don't get any response if a release_complete is received (or a release in release state)
1858 while(p_epointlist) { // only if not already released
1859 struct lcr_msg *message;
1860 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1861 if (p_m_d_collect_cause) {
1862 message->param.disconnectinfo.cause = p_m_d_collect_cause;
1863 message->param.disconnectinfo.location = p_m_d_collect_location;
1865 message->param.disconnectinfo.cause = CAUSE_NOUSER;
1866 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1868 message_put(message);
1870 free_epointlist(p_epointlist);
1872 new_state(PORT_STATE_RELEASE);
1877 l1l2l3_trace_header(p_m_mISDNport, this, L3_UNKNOWN_IND, DIRECTION_IN);
1878 add_trace("unhandled", "cmd", "0x%x", cmd);
1883 void Pdss1::new_state(int state)
1885 // class Endpoint *epoint;
1888 if (state == PORT_STATE_IN_OVERLAP) {
1889 if (p_m_mISDNport->ifport->tout_dialing)
1890 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_dialing, 0);
1892 if (state != p_state) {
1893 unsched_timer(&p_m_timeout);
1894 if (state == PORT_STATE_IN_SETUP
1895 || state == PORT_STATE_OUT_SETUP
1896 || state == PORT_STATE_IN_OVERLAP
1897 || state == PORT_STATE_OUT_OVERLAP) {
1898 if (p_m_mISDNport->ifport->tout_setup)
1899 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_setup, 0);
1901 if (state == PORT_STATE_IN_PROCEEDING
1902 || state == PORT_STATE_OUT_PROCEEDING) {
1903 if (p_m_mISDNport->ifport->tout_proceeding)
1904 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_proceeding, 0);
1906 if (state == PORT_STATE_IN_ALERTING
1907 || state == PORT_STATE_OUT_ALERTING) {
1908 if (p_m_mISDNport->ifport->tout_alerting)
1909 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_alerting, 0);
1912 if (state == PORT_STATE_CONNECT
1913 || state == PORT_STATE_CONNECT_WAITING) {
1914 if (p_m_mISDNport->ifport->tout_connect)
1915 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_connect, 0);
1918 if (state == PORT_STATE_IN_DISCONNECT
1919 || state == PORT_STATE_OUT_DISCONNECT) {
1920 if (p_m_mISDNport->ifport->tout_disconnect)
1921 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_disconnect, 0);
1925 Port::new_state(state);
1929 /* deletes only if l3id is release, otherwhise it will be triggered then */
1930 static int delete_event(struct lcr_work *work, void *instance, int index)
1932 class Pdss1 *isdnport = (class Pdss1 *)instance;
1934 if (!isdnport->p_m_d_l3id)
1942 * handles all messages from endpoint
1944 /* MESSAGE_INFORMATION */
1945 void Pdss1::message_information(unsigned int epoint_id, int message_id, union parameter *param)
1948 char *display = param->information.display;
1949 char *number = param->information.id;
1950 int max = p_m_mISDNport->ifport->dialmax;
1952 while (number[0]) { /* as long we have something to dial */
1953 if (max > (int)strlen(number) || max == 0)
1954 max = (int)strlen(number);
1956 l3m = create_l3msg();
1957 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
1958 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)number, max);
1959 if ((p_m_d_ntmode || p_m_d_tespecial) && display[0]) {
1960 enc_ie_display(l3m, (unsigned char *)display);
1961 display = (char *)"";
1964 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
1972 void Pdss1::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1975 #ifdef OLD_MT_ASSIGN
1978 int plan, type, screen, present, reason;
1979 int plan2, type2, screen2, present2;
1980 int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
1981 int channel, exclusive;
1982 struct epoint_list *epointlist;
1983 int max = p_m_mISDNport->ifport->dialmax;
1985 /* release if port is blocked */
1986 if (p_m_mISDNport->ifport->block) {
1987 struct lcr_msg *message;
1989 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1990 message->param.disconnectinfo.cause = 27; // temp. unavail.
1991 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1992 message_put(message);
1993 new_state(PORT_STATE_RELEASE);
1994 trigger_work(&p_m_d_delete);
1998 /* copy setup infos to port */
1999 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
2000 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
2001 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
2002 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
2003 /* screen outgoing caller id */
2004 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
2005 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
2006 do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_m_mISDNport->ifport->interface->name);
2008 /* only display at connect state: this case happens if endpoint is in connected mode */
2009 if (p_state==PORT_STATE_CONNECT) {
2010 if (p_type!=PORT_TYPE_DSS1_NT_OUT
2011 && p_type!=PORT_TYPE_DSS1_NT_IN)
2013 if (p_callerinfo.display[0]) {
2014 /* sending information */
2015 l3m = create_l3msg();
2016 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2017 if (p_m_d_ntmode || p_m_d_tespecial)
2018 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2020 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
2025 /* attach only if not already */
2026 epointlist = p_epointlist;
2028 if (epointlist->epoint_id == epoint_id)
2030 epointlist = epointlist->next;
2033 epointlist_new(epoint_id);
2037 if (p_m_b_channel) {
2038 channel = p_m_b_channel;
2039 exclusive = p_m_b_exclusive;
2041 channel = CHANNEL_ANY;
2042 /* nt-port with no channel, not reserverd */
2043 if (!p_m_b_channel && !p_m_b_reserve && p_type==PORT_TYPE_DSS1_NT_OUT)
2044 channel = CHANNEL_NO;
2047 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_REQ, DIRECTION_OUT);
2048 #ifdef OLD_MT_ASSIGN
2049 /* see MT_ASSIGN notes at do_layer3() */
2051 ret = p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_ASSIGN, 0, NULL);
2052 if (mt_assign_pid == 0 || ret < 0)
2053 p_m_d_l3id = mt_assign_pid;
2056 p_m_d_l3id = request_new_pid(p_m_mISDNport->ml3);
2057 if (p_m_d_l3id == MISDN_PID_NONE)
2060 struct lcr_msg *message;
2062 add_trace("callref", NULL, "no free id");
2064 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2065 message->param.disconnectinfo.cause = 47;
2066 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2067 message_put(message);
2068 new_state(PORT_STATE_RELEASE);
2069 trigger_work(&p_m_d_delete);
2072 #ifdef OLD_MT_ASSIGN
2073 p_m_d_l3id = mt_assign_pid;
2076 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2079 /* preparing setup message */
2080 l3m = create_l3msg();
2081 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_REQ, DIRECTION_OUT);
2082 /* channel information */
2083 if (p_m_d_ntmode || channel != CHANNEL_ANY) /* only omit channel id in te-mode/any channel */
2084 enc_ie_channel_id(l3m, exclusive, channel);
2085 /* caller information */
2087 switch (p_callerinfo.ntype) {
2088 case INFO_NTYPE_UNKNOWN:
2091 case INFO_NTYPE_INTERNATIONAL:
2094 case INFO_NTYPE_NATIONAL:
2097 case INFO_NTYPE_SUBSCRIBER:
2100 default: /* INFO_NTYPE_NOTPRESENT */
2104 switch (p_callerinfo.screen) {
2105 case INFO_SCREEN_USER:
2108 case INFO_SCREEN_USER_VERIFIED_PASSED:
2111 case INFO_SCREEN_USER_VERIFIED_FAILED:
2114 default: /* INFO_SCREEN_NETWORK */
2118 switch (p_callerinfo.present) {
2119 case INFO_PRESENT_ALLOWED:
2122 case INFO_PRESENT_RESTRICTED:
2125 default: /* INFO_PRESENT_NOTAVAIL */
2129 /* caller information 2 */
2131 switch (p_callerinfo.ntype2) {
2132 case INFO_NTYPE_UNKNOWN:
2135 case INFO_NTYPE_INTERNATIONAL:
2138 case INFO_NTYPE_NATIONAL:
2141 case INFO_NTYPE_SUBSCRIBER:
2144 default: /* INFO_NTYPE_NOTPRESENT */
2148 switch (p_callerinfo.screen2) {
2149 case INFO_SCREEN_USER:
2152 case INFO_SCREEN_USER_VERIFIED_PASSED:
2155 case INFO_SCREEN_USER_VERIFIED_FAILED:
2158 default: /* INFO_SCREEN_NETWORK */
2162 switch (p_callerinfo.present2) {
2163 case INFO_PRESENT_ALLOWED:
2166 case INFO_PRESENT_RESTRICTED:
2169 default: /* INFO_PRESENT_NOTAVAIL */
2174 enc_ie_calling_pn(l3m, type, plan, present, screen, (unsigned char *)p_callerinfo.id, type2, plan2, present2, screen2, (unsigned char *)p_callerinfo.id2);
2175 /* dialing information */
2176 if (p_dialinginfo.id[0]) { /* only if we have something to dial */
2177 if (max > (int)strlen(p_dialinginfo.id) || max == 0)
2178 max = (int)strlen(p_dialinginfo.id);
2179 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max);
2180 SCPY(p_m_d_queue, p_dialinginfo.id + max);
2183 if (p_dialinginfo.keypad[0])
2184 enc_ie_keypad(l3m, (unsigned char *)p_dialinginfo.keypad);
2185 /* sending complete */
2186 if (p_dialinginfo.sending_complete)
2187 enc_ie_complete(l3m, 1);
2188 /* sending user-user */
2189 if (param->setup.useruser.len) {
2190 enc_ie_useruser(l3m, param->setup.useruser.protocol, param->setup.useruser.data, param->setup.useruser.len);
2192 /* redirecting number */
2194 switch (p_redirinfo.ntype) {
2195 case INFO_NTYPE_UNKNOWN:
2198 case INFO_NTYPE_INTERNATIONAL:
2201 case INFO_NTYPE_NATIONAL:
2204 case INFO_NTYPE_SUBSCRIBER:
2207 default: /* INFO_NTYPE_NOTPRESENT */
2211 switch (p_redirinfo.screen) {
2212 case INFO_SCREEN_USER:
2215 case INFO_SCREEN_USER_VERIFIED_PASSED:
2218 case INFO_SCREEN_USER_VERIFIED_FAILED:
2221 default: /* INFO_SCREE_NETWORK */
2225 switch (p_redirinfo.reason) {
2226 case INFO_REDIR_BUSY:
2229 case INFO_REDIR_NORESPONSE:
2232 case INFO_REDIR_UNCONDITIONAL:
2235 case INFO_REDIR_CALLDEFLECT:
2238 case INFO_REDIR_OUTOFORDER:
2241 default: /* INFO_REDIR_UNKNOWN */
2245 switch (p_redirinfo.present) {
2246 case INFO_PRESENT_ALLOWED:
2249 case INFO_PRESENT_RESTRICTED:
2252 default: /* INFO_PRESENT_NOTAVAIL */
2256 /* sending redirecting number only in ntmode */
2257 if (type >= 0 && (p_m_d_ntmode || p_m_d_tespecial))
2258 enc_ie_redir_nr(l3m, type, plan, present, screen, reason, (unsigned char *)p_redirinfo.id);
2259 /* bearer capability */
2260 //printf("hlc=%d\n",p_capainfo.hlc);
2262 capability = p_capainfo.bearer_capa;
2263 mode = p_capainfo.bearer_mode;
2264 rate = (mode==INFO_BMODE_CIRCUIT)?0x10:0x00;
2265 switch (p_capainfo.bearer_info1) {
2266 case INFO_INFO1_NONE:
2270 user = p_capainfo.bearer_info1 & 0x7f;
2273 enc_ie_bearer(l3m, coding, capability, mode, rate, -1, user);
2275 if (p_capainfo.hlc) {
2279 hlc = p_capainfo.hlc & 0x7f;
2281 if (p_capainfo.exthlc)
2282 exthlc = p_capainfo.exthlc & 0x7f;
2283 enc_ie_hlc(l3m, coding, interpretation, presentation, hlc, exthlc);
2287 if (p_callerinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2288 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2289 /* nt-mode: CNIP (calling name identification presentation) */
2290 // if (p_callerinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2291 // enc_facility_centrex(&setup->FACILITY, dmsg, (unsigned char *)p_callerinfo.name, 1);
2294 /* send setup message now */
2295 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SETUP, p_m_d_l3id, l3m);
2297 new_state(PORT_STATE_OUT_SETUP);
2300 /* MESSAGE_FACILITY */
2301 void Pdss1::message_facility(unsigned int epoint_id, int message_id, union parameter *param)
2305 /* facility will not be sent to external lines */
2306 if (!p_m_d_ntmode && !p_m_d_tespecial)
2309 /* sending facility */
2310 l3m = create_l3msg();
2311 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2312 enc_ie_facility(l3m, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len);
2314 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
2318 void Pdss1::message_3pty(unsigned int epoint_id, int message_id, union parameter *param)
2321 unsigned char fac_ie[256];
2322 struct asn1_parm fac;
2324 /* encode 3PTY facility */
2325 memset(&fac, 0, sizeof(fac));
2327 if (param->threepty.result) {
2328 fac.comp = CompReturnResult;
2329 fac.u.retResult.invokeId = param->threepty.invoke_id;
2331 if (param->threepty.error) {
2332 fac.comp = CompReturnError;
2333 fac.u.retError.invokeId = param->threepty.invoke_id;
2334 fac.u.retError.errorValue = FacError_Gen_InvalidCallState;
2336 fac.u.retResult.operationValuePresent = 1;
2337 if (param->threepty.begin)
2338 fac.u.retResult.operationValue = Fac_Begin3PTY;
2339 if (param->threepty.end)
2340 fac.u.retResult.operationValue = Fac_End3PTY;
2341 encodeFac(fac_ie, &fac);
2343 /* sending facility */
2344 l3m = create_l3msg();
2345 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2346 enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]);
2348 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
2351 /* MESSAGE_NOTIFY */
2352 void Pdss1::message_notify(unsigned int epoint_id, int message_id, union parameter *param)
2356 int plan = 0, type = -1, present = 0;
2358 if (p_m_mISDNport->ifport->nonotify) {
2359 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
2360 add_trace("info", NULL, "blocked by config");
2365 // printf("if = %d\n", param->notifyinfo.notify);
2366 if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
2367 notify = param->notifyinfo.notify & 0x7f;
2372 switch (param->notifyinfo.ntype) {
2373 case INFO_NTYPE_UNKNOWN:
2376 case INFO_NTYPE_INTERNATIONAL:
2379 case INFO_NTYPE_NATIONAL:
2382 case INFO_NTYPE_SUBSCRIBER:
2385 default: /* INFO_NTYPE_UNKNOWN */
2389 switch (param->notifyinfo.present) {
2390 case INFO_PRESENT_ALLOWED:
2393 case INFO_PRESENT_RESTRICTED:
2396 default: /* INFO_PRESENT_NOTAVAIL */
2402 if (notify<0 && !param->notifyinfo.display[0]) {
2403 /* nothing to notify, nothing to display */
2408 if (p_state!=PORT_STATE_CONNECT && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING) {
2409 /* queue notification */
2410 if (p_m_d_notify_pending)
2411 message_free(p_m_d_notify_pending);
2412 p_m_d_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
2413 memcpy(&p_m_d_notify_pending->param, param, sizeof(union parameter));
2415 /* sending notification */
2416 l3m = create_l3msg();
2417 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
2418 enc_ie_notify(l3m, notify);
2419 /* sending redirection number only in ntmode */
2420 if (type >= 0 && (p_m_d_ntmode || p_m_d_tespecial))
2421 enc_ie_redir_dn(l3m, type, plan, present, (unsigned char *)param->notifyinfo.id);
2422 if (param->notifyinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2423 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2425 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_NOTIFY, p_m_d_l3id, l3m);
2427 } else if (p_m_d_ntmode || p_m_d_tespecial) {
2428 /* sending information */
2429 l3m = create_l3msg();
2430 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2431 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2433 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
2437 /* MESSAGE_OVERLAP */
2438 void Pdss1::message_overlap(unsigned int epoint_id, int message_id, union parameter *param)
2442 /* in case of sending complete, we proceed */
2443 if (p_dialinginfo.sending_complete) {
2444 PDEBUG(DEBUG_ISDN, "sending proceeding instead of setup_acknowledge, because address is complete.\n");
2445 message_proceeding(epoint_id, message_id, param);
2449 /* sending setup_acknowledge */
2450 l3m = create_l3msg();
2451 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_REQ, DIRECTION_OUT);
2452 /* channel information */
2453 if (p_state == PORT_STATE_IN_SETUP)
2454 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2455 /* progress information */
2456 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2457 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2458 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2459 if (p_m_mISDNport->tones)
2460 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2462 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SETUP_ACKNOWLEDGE, p_m_d_l3id, l3m);
2464 new_state(PORT_STATE_IN_OVERLAP);
2467 /* MESSAGE_PROCEEDING */
2468 void Pdss1::message_proceeding(unsigned int epoint_id, int message_id, union parameter *param)
2472 /* sending proceeding */
2473 l3m = create_l3msg();
2474 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2475 /* channel information */
2476 if (p_state == PORT_STATE_IN_SETUP)
2477 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2478 /* progress information */
2479 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2480 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2481 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2482 if (p_m_mISDNport->tones)
2483 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2485 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2487 new_state(PORT_STATE_IN_PROCEEDING);
2490 /* MESSAGE_ALERTING */
2491 void Pdss1::message_alerting(unsigned int epoint_id, int message_id, union parameter *param)
2495 /* NT-MODE in setup state we must send PROCEEDING first */
2496 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
2497 /* sending proceeding */
2498 l3m = create_l3msg();
2499 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2500 /* channel information */
2501 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2502 /* progress information */
2503 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2504 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2505 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2506 if (p_m_mISDNport->tones)
2507 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2509 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2510 new_state(PORT_STATE_IN_PROCEEDING);
2513 /* sending alerting */
2514 l3m = create_l3msg();
2515 l1l2l3_trace_header(p_m_mISDNport, this, L3_ALERTING_REQ, DIRECTION_OUT);
2516 /* channel information */
2517 if (p_state == PORT_STATE_IN_SETUP)
2518 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2519 /* progress information */
2520 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2521 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2522 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2523 if (p_m_mISDNport->tones)
2524 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2526 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_ALERTING, p_m_d_l3id, l3m);
2528 new_state(PORT_STATE_IN_ALERTING);
2531 /* MESSAGE_CONNECT */
2532 void Pdss1::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
2535 int type, plan, present, screen;
2536 class Endpoint *epoint;
2537 time_t current_time;
2539 /* NT-MODE in setup state we must send PROCEEDING first */
2540 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
2541 /* sending proceeding */
2542 l3m = create_l3msg();
2543 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2544 /* channel information */
2545 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2547 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2548 new_state(PORT_STATE_IN_PROCEEDING);
2551 /* copy connected information */
2552 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
2553 /* screen outgoing caller id */
2554 do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface->name);
2556 /* only display at connect state */
2557 if (p_state == PORT_STATE_CONNECT)
2558 if (p_connectinfo.display[0]) {
2559 /* sending information */
2560 l3m = create_l3msg();
2561 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2562 if (p_m_d_ntmode || p_m_d_tespecial)
2563 enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
2565 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
2569 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) {
2570 /* connect command only possible in setup, proceeding or alerting state */
2574 /* preparing connect message */
2575 l3m = create_l3msg();
2576 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_REQ, DIRECTION_OUT);
2577 /* connect information */
2579 switch (p_connectinfo.ntype) {
2580 case INFO_NTYPE_UNKNOWN:
2583 case INFO_NTYPE_INTERNATIONAL:
2586 case INFO_NTYPE_NATIONAL:
2589 case INFO_NTYPE_SUBSCRIBER:
2592 default: /* INFO_NTYPE_NOTPRESENT */
2596 switch (param->connectinfo.screen) {
2597 case INFO_SCREEN_USER:
2600 case INFO_SCREEN_USER_VERIFIED_PASSED:
2603 case INFO_SCREEN_USER_VERIFIED_FAILED:
2606 default: /* INFO_SCREE_NETWORK */
2610 switch (p_connectinfo.present) {
2611 case INFO_PRESENT_ALLOWED:
2614 case INFO_PRESENT_RESTRICTED:
2617 default: /* INFO_PRESENT_NOTAVAIL */
2622 enc_ie_connected_pn(l3m, type, plan, present, screen, (unsigned char *)p_connectinfo.id);
2624 if (p_connectinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2625 enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
2626 /* nt-mode: CONP (connected name identification presentation) */
2627 // if (p_connectinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2628 // enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
2630 if (p_m_d_ntmode || p_m_d_tespecial) {
2631 epoint = find_epoint_id(epoint_id);
2632 time(¤t_time);
2633 enc_ie_date(l3m, current_time, p_settings.no_seconds);
2636 /* finally send message */
2637 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CONNECT, p_m_d_l3id, l3m);
2640 new_state(PORT_STATE_CONNECT);
2642 new_state(PORT_STATE_CONNECT_WAITING);
2646 /* MESSAGE_DISCONNECT */
2647 void Pdss1::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
2650 struct lcr_msg *message;
2653 /* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
2654 // if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
2655 if (/* ||*/ p_state==PORT_STATE_OUT_SETUP) {
2656 /* sending release to endpoint */
2657 while(p_epointlist) {
2658 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
2659 memcpy(&message->param, param, sizeof(union parameter));
2660 message_put(message);
2662 free_epointlist(p_epointlist);
2664 /* sending release */
2665 l3m = create_l3msg();
2666 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
2668 enc_ie_cause(l3m, (!p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_REMOTE:param->disconnectinfo.location, param->disconnectinfo.cause);
2670 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
2671 new_state(PORT_STATE_RELEASE);
2672 trigger_work(&p_m_d_delete);
2676 /* workarround: NT-MODE in setup state we must send PROCEEDING first to make it work */
2677 if (p_state==PORT_STATE_IN_SETUP) {
2678 /* sending proceeding */
2679 l3m = create_l3msg();
2680 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2681 /* channel information */
2682 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2683 /* progress information */
2684 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2685 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2686 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2687 if (p_m_mISDNport->tones)
2688 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2690 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2691 new_state(PORT_STATE_IN_PROCEEDING);
2694 /* sending disconnect */
2695 l3m = create_l3msg();
2696 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
2697 /* progress information */
2698 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2699 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2700 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2701 if (p_m_mISDNport->tones)
2702 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2704 enc_ie_cause(l3m, (!p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_REMOTE:param->disconnectinfo.location, param->disconnectinfo.cause);
2706 if (param->disconnectinfo.display[0])
2707 p = param->disconnectinfo.display;
2708 if (p) if (*p && (p_m_d_ntmode || p_m_d_tespecial))
2709 enc_ie_display(l3m, (unsigned char *)p);
2711 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_DISCONNECT, p_m_d_l3id, l3m);
2712 new_state(PORT_STATE_OUT_DISCONNECT);
2715 /* MESSAGE_RELEASE */
2716 void Pdss1::message_release(unsigned int epoint_id, int message_id, union parameter *param)
2719 class Endpoint *epoint;
2723 * if we are on incoming call setup, we may reject by sending a release_complete
2724 * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
2726 if (p_state==PORT_STATE_IN_SETUP
2727 || p_state==PORT_STATE_OUT_SETUP) {
2728 //#warning remove me
2729 //PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
2730 /* sending release complete */
2731 l3m = create_l3msg();
2732 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
2734 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2736 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
2737 new_state(PORT_STATE_RELEASE);
2739 free_epointid(epoint_id);
2740 // wait for callref to be released
2744 * we may only release during incoming disconnect state.
2745 * this means that the endpoint doesnt require audio anymore
2747 if (p_state == PORT_STATE_IN_DISCONNECT
2748 || p_state == PORT_STATE_OUT_DISCONNECT
2749 || param->disconnectinfo.force) {
2750 /* sending release */
2751 l3m = create_l3msg();
2752 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
2754 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2756 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
2757 new_state(PORT_STATE_RELEASE);
2759 free_epointid(epoint_id);
2760 // wait for callref to be released
2766 wirklich erst proceeding?:
2767 /* NT-MODE in setup state we must send PROCEEDING first */
2768 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
2769 CALL_PROCEEDING_t *proceeding;
2771 /* sending proceeding */
2772 l3m = create_l3msg();
2773 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2774 /* channel information */
2775 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2776 /* progress information */
2777 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2778 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2779 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2780 if (p_m_mISDNport->tones)
2781 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2783 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2787 /* sending disconnect */
2788 l3m = create_l3msg();
2789 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
2790 /* progress information */
2791 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2792 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2793 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2794 if (p_m_mISDNport->tones)
2795 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2797 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2799 epoint = find_epoint_id(epoint_id);
2800 if (param->disconnectinfo.display[0])
2801 p = param->disconnectinfo.display;
2802 if (p) if (*p && (p_m_d_ntmode || p_m_d_tespecial))
2803 enc_ie_display(l3m, (unsigned char *)p);
2805 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_DISCONNECT, p_m_d_l3id, l3m);
2806 new_state(PORT_STATE_OUT_DISCONNECT);
2808 free_epointid(epoint_id);
2809 // wait for release and callref to be released
2810 //#warning remove me
2811 //PDEBUG(DEBUG_LOG, "JOLLY sending disconnect %d\n", p_serial);
2816 * endpoint sends messages to the port
2818 int Pdss1::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
2820 if (PmISDN::message_epoint(epoint_id, message_id, param))
2823 switch(message_id) {
2824 case MESSAGE_INFORMATION: /* overlap dialing */
2825 if (p_type==PORT_TYPE_DSS1_NT_OUT
2826 && p_state!=PORT_STATE_OUT_OVERLAP
2827 && p_state!=PORT_STATE_CONNECT
2828 && p_state!=PORT_STATE_OUT_DISCONNECT
2829 && p_state!=PORT_STATE_IN_DISCONNECT) {
2832 if (p_type==PORT_TYPE_DSS1_TE_OUT
2833 && p_state!=PORT_STATE_OUT_OVERLAP
2834 && p_state!=PORT_STATE_OUT_PROCEEDING
2835 && p_state!=PORT_STATE_OUT_ALERTING
2836 && p_state!=PORT_STATE_CONNECT
2837 && p_state!=PORT_STATE_OUT_DISCONNECT
2838 && p_state!=PORT_STATE_IN_DISCONNECT) {
2841 if ((p_type==PORT_TYPE_DSS1_NT_IN || p_type==PORT_TYPE_DSS1_TE_IN)
2842 && p_state!=PORT_STATE_IN_OVERLAP
2843 && p_state!=PORT_STATE_IN_PROCEEDING
2844 && p_state!=PORT_STATE_IN_ALERTING
2845 && p_state!=PORT_STATE_CONNECT
2846 && p_state!=PORT_STATE_CONNECT_WAITING
2847 && p_state!=PORT_STATE_OUT_DISCONNECT
2848 && p_state!=PORT_STATE_IN_DISCONNECT) {
2851 message_information(epoint_id, message_id, param);
2854 case MESSAGE_SETUP: /* dial-out command received from epoint */
2855 if (p_state!=PORT_STATE_IDLE
2856 && p_state!=PORT_STATE_CONNECT) {
2857 PERROR("Pdss1(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
2860 if (p_epointlist && p_state==PORT_STATE_IDLE)
2861 FATAL("Pdss1(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
2862 message_setup(epoint_id, message_id, param);
2865 case MESSAGE_NOTIFY: /* display and notifications */
2866 message_notify(epoint_id, message_id, param);
2869 case MESSAGE_FACILITY: /* facility message */
2870 message_facility(epoint_id, message_id, param);
2873 case MESSAGE_3PTY: /* begin result message */
2874 message_3pty(epoint_id, message_id, param);
2877 case MESSAGE_OVERLAP: /* more information is needed */
2878 if (p_state!=PORT_STATE_IN_SETUP) {
2881 message_overlap(epoint_id, message_id, param);
2884 case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
2885 if (p_state!=PORT_STATE_IN_SETUP
2886 && p_state!=PORT_STATE_IN_OVERLAP) {
2889 message_proceeding(epoint_id, message_id, param);
2890 if (p_m_d_notify_pending) {
2891 /* send pending notify message during connect */
2892 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2893 message_free(p_m_d_notify_pending);
2894 p_m_d_notify_pending = NULL;
2898 case MESSAGE_ALERTING: /* call of endpoint is ringing */
2899 if (p_state!=PORT_STATE_IN_SETUP
2900 && p_state!=PORT_STATE_IN_OVERLAP
2901 && p_state!=PORT_STATE_IN_PROCEEDING) {
2904 message_alerting(epoint_id, message_id, param);
2905 if (p_m_d_notify_pending) {
2906 /* send pending notify message during connect */
2907 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2908 message_free(p_m_d_notify_pending);
2909 p_m_d_notify_pending = NULL;
2913 case MESSAGE_CONNECT: /* call of endpoint is connected */
2914 if (p_state!=PORT_STATE_IN_SETUP
2915 && p_state!=PORT_STATE_IN_OVERLAP
2916 && p_state!=PORT_STATE_IN_PROCEEDING
2917 && p_state!=PORT_STATE_IN_ALERTING
2918 && !(p_state==PORT_STATE_CONNECT && p_m_d_ntmode)) {
2921 message_connect(epoint_id, message_id, param);
2922 if (p_m_d_notify_pending) {
2923 /* send pending notify message during connect */
2924 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2925 message_free(p_m_d_notify_pending);
2926 p_m_d_notify_pending = NULL;
2930 case MESSAGE_DISCONNECT: /* call has been disconnected */
2931 if (p_state!=PORT_STATE_IN_SETUP
2932 && p_state!=PORT_STATE_IN_OVERLAP
2933 && p_state!=PORT_STATE_IN_PROCEEDING
2934 && p_state!=PORT_STATE_IN_ALERTING
2935 && p_state!=PORT_STATE_OUT_SETUP
2936 && p_state!=PORT_STATE_OUT_OVERLAP
2937 && p_state!=PORT_STATE_OUT_PROCEEDING
2938 && p_state!=PORT_STATE_OUT_ALERTING
2939 && p_state!=PORT_STATE_CONNECT
2940 && p_state!=PORT_STATE_CONNECT_WAITING) {
2943 message_disconnect(epoint_id, message_id, param);
2946 case MESSAGE_RELEASE: /* release isdn port */
2947 if (p_state==PORT_STATE_RELEASE) {
2950 message_release(epoint_id, message_id, param);
2954 PERROR("Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message_id);
2963 * data from isdn-stack (layer-3) to pbx (port class)
2965 int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2971 PDEBUG(DEBUG_ISDN, "cmd(0x%x) pid(0x%x)\n", cmd, pid);
2974 PDEBUG(DEBUG_ISDN, "ignoring dummy process from phone.\n");
2978 /* find Port object of type ISDN */
2982 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
2983 pdss1 = (class Pdss1 *)port;
2984 /* check out correct stack and id */
2985 if (pdss1->p_m_mISDNport == mISDNport) {
2986 if (pdss1->p_m_d_l3id & MISDN_PID_CR_FLAG) {
2987 /* local callref, so match value only */
2988 if ((pdss1->p_m_d_l3id & MISDN_PID_CRVAL_MASK) == (pid & MISDN_PID_CRVAL_MASK))
2991 /* remote callref, ref + channel id */
2992 if (pdss1->p_m_d_l3id == pid)
3000 /* aktueller prozess */
3002 if (cmd == MT_ASSIGN) {
3003 /* stack gives us new layer 3 id (during connect) */
3004 l1l2l3_trace_header(mISDNport, pdss1, L3_NEW_L3ID_IND, DIRECTION_IN);
3005 add_trace("callref", "old", "0x%x", pdss1->p_m_d_l3id);
3006 /* nt-library now gives us a new id via CC_SETUP_CONFIRM */
3007 if ((pdss1->p_m_d_l3id&MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER)
3008 PERROR(" strange setup-procid 0x%x\n", pdss1->p_m_d_l3id);
3009 pdss1->p_m_d_l3id = pid;
3010 if (port->p_state == PORT_STATE_CONNECT)
3011 pdss1->p_m_d_ces = pid >> 16;
3012 add_trace("callref", "new", "0x%x", pdss1->p_m_d_l3id);
3016 /* if process id is master process, but a child disconnects */
3017 if (mISDNport->ntmode
3018 && (pid & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3019 && (pdss1->p_m_d_l3id & MISDN_PID_CRTYPE_MASK) == MISDN_PID_MASTER) {
3020 if (cmd == MT_DISCONNECT
3021 || cmd == MT_RELEASE) {
3022 /* send special indication for child disconnect */
3023 pdss1->disconnect_ind_i(cmd, pid, l3m);
3026 if (cmd == MT_RELEASE_COMPLETE)
3029 /* if we have child pid and got different child pid message, ignore */
3030 if (mISDNport->ntmode
3031 && (pid & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3032 && (pdss1->p_m_d_l3id & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3033 && pid != pdss1->p_m_d_l3id)
3036 /* process message */
3037 pdss1->message_isdn(cmd, pid, l3m);
3044 /* creating port object, transparent until setup with hdlc */
3045 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3046 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
3048 FATAL("Cannot create Port instance.\n");
3049 pdss1->message_isdn(cmd, pid, l3m);
3053 /* creating port object, transparent until setup with hdlc */
3054 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3055 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
3056 FATAL("Cannot create Port instance.\n");
3057 pdss1->message_isdn(cmd, pid, l3m);
3061 PDEBUG(DEBUG_ISDN, "unused call ref released (l3id=0x%x)\n", pid);
3064 case MT_RELEASE_COMPLETE:
3065 PERROR("must be ignored by stack, not sent to app\n");
3069 // facility als broadcast
3073 // L2 became idle - we could sent a MT_L2RELEASE if we are the L2 master
3074 PDEBUG(DEBUG_ISDN, "Got L2 idle\n");
3078 PERROR("unhandled message: cmd(0x%x) pid(0x%x)\n", cmd, pid);
3081 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT) {
3082 pdss1 = (class Pdss1 *)port;
3083 /* check out correct stack */
3084 if (pdss1->p_m_mISDNport == mISDNport)
3085 /* check out correct id */
3086 PERROR("unhandled message: pid=%x is not associated with port-dinfo=%x\n", pid, pdss1->p_m_d_l3id);