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, struct interface *interface, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, interface, 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_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_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);
1679 case Fac_EctExecute:
1680 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TRANSFER);
1681 message->param.transfer.invoke = 1;
1682 message->param.transfer.invoke_id = fac.u.inv.invokeId;
1683 message_put(message);
1693 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
1694 message->param.facilityinfo.len = fac_len;
1695 memcpy(message->param.facilityinfo.data, fac_ie + 1, fac_len);
1696 message_put(message);
1700 /* CC_PROGRESS INDICATION */
1701 void Pdss1::progress_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1703 int coding, location, progress;
1705 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROGRESS_IND, DIRECTION_IN);
1706 dec_ie_progress(l3m, &coding, &location, &progress);
1709 if (progress >= 0) {
1710 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
1711 message->param.progressinfo.progress = progress;
1712 message->param.progressinfo.location = location;
1713 message_put(message);
1719 * handler for isdn connections
1720 * incoming information are parsed and sent via message to the endpoint
1722 void Pdss1::message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1729 PERROR("Pdss1(%s) timeout without cause.\n", p_name);
1732 if (l3m->cause[0] != 5) {
1733 PERROR("Pdss1(%s) expecting timeout with timer diagnostic. (got len=%d)\n", p_name, l3m->cause[0]);
1736 timer = (l3m->cause[3]-'0')*100;
1737 timer += (l3m->cause[4]-'0')*10;
1738 timer += (l3m->cause[5]-'0');
1739 l1l2l3_trace_header(p_m_mISDNport, this, L3_TIMEOUT_IND, DIRECTION_IN);
1740 add_trace("timer", NULL, "%d", timer);
1743 t312_timeout_ind(cmd, pid, l3m);
1747 if (p_state != PORT_STATE_IDLE)
1749 setup_ind(cmd, pid, l3m);
1752 case MT_INFORMATION:
1753 information_ind(cmd, pid, l3m);
1756 case MT_SETUP_ACKNOWLEDGE:
1757 if (p_state != PORT_STATE_OUT_SETUP) {
1758 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
1761 setup_acknowledge_ind(cmd, pid, l3m);
1764 case MT_CALL_PROCEEDING:
1765 if (p_state != PORT_STATE_OUT_SETUP
1766 && p_state != PORT_STATE_OUT_OVERLAP) {
1767 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
1770 proceeding_ind(cmd, pid, l3m);
1774 if (p_state != PORT_STATE_OUT_SETUP
1775 && p_state != PORT_STATE_OUT_OVERLAP
1776 && p_state != PORT_STATE_OUT_PROCEEDING) {
1777 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
1780 alerting_ind(cmd, pid, l3m);
1784 if (p_state != PORT_STATE_OUT_SETUP
1785 && p_state != PORT_STATE_OUT_OVERLAP
1786 && p_state != PORT_STATE_OUT_PROCEEDING
1787 && p_state != PORT_STATE_OUT_ALERTING) {
1788 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);
1791 connect_ind(cmd, pid, l3m);
1792 if (p_m_d_notify_pending) {
1793 /* send pending notify message during connect */
1794 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
1795 message_free(p_m_d_notify_pending);
1796 p_m_d_notify_pending = NULL;
1800 case MT_CONNECT_ACKNOWLEDGE:
1801 if (p_state == PORT_STATE_CONNECT_WAITING)
1802 new_state(PORT_STATE_CONNECT);
1803 if (p_m_d_notify_pending) {
1804 /* send pending notify message during connect-ack */
1805 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
1806 message_free(p_m_d_notify_pending);
1807 p_m_d_notify_pending = NULL;
1812 disconnect_ind(cmd, pid, l3m);
1816 release_ind(cmd, pid, l3m);
1819 case MT_RELEASE_COMPLETE:
1820 release_complete_ind(cmd, pid, l3m);
1824 restart_ind(cmd, pid, l3m);
1828 notify_ind(cmd, pid, l3m);
1832 hold_ind(cmd, pid, l3m);
1836 retrieve_ind(cmd, pid, l3m);
1840 suspend_ind(cmd, pid, l3m);
1844 resume_ind(cmd, pid, l3m);
1848 facility_ind(cmd, pid, l3m);
1852 progress_ind(cmd, pid, l3m);
1856 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_L3ID_IND, DIRECTION_IN);
1857 add_trace("callref", NULL, "0x%x", p_m_d_l3id);
1860 trigger_work(&p_m_d_delete);
1862 /* sending release to endpoint in case we still have an endpoint
1863 * this is because we don't get any response if a release_complete is received (or a release in release state)
1865 while(p_epointlist) { // only if not already released
1866 struct lcr_msg *message;
1867 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1868 if (p_m_d_collect_cause) {
1869 message->param.disconnectinfo.cause = p_m_d_collect_cause;
1870 message->param.disconnectinfo.location = p_m_d_collect_location;
1872 message->param.disconnectinfo.cause = CAUSE_NOUSER;
1873 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1875 message_put(message);
1877 free_epointlist(p_epointlist);
1879 new_state(PORT_STATE_RELEASE);
1884 l1l2l3_trace_header(p_m_mISDNport, this, L3_UNKNOWN_IND, DIRECTION_IN);
1885 add_trace("unhandled", "cmd", "0x%x", cmd);
1890 void Pdss1::new_state(int state)
1892 // class Endpoint *epoint;
1895 if (state == PORT_STATE_IN_OVERLAP) {
1896 if (p_m_mISDNport->ifport->tout_dialing)
1897 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_dialing, 0);
1899 if (state != p_state) {
1900 unsched_timer(&p_m_timeout);
1901 if (state == PORT_STATE_IN_SETUP
1902 || state == PORT_STATE_OUT_SETUP
1903 || state == PORT_STATE_IN_OVERLAP
1904 || state == PORT_STATE_OUT_OVERLAP) {
1905 if (p_m_mISDNport->ifport->tout_setup)
1906 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_setup, 0);
1908 if (state == PORT_STATE_IN_PROCEEDING
1909 || state == PORT_STATE_OUT_PROCEEDING) {
1910 if (p_m_mISDNport->ifport->tout_proceeding)
1911 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_proceeding, 0);
1913 if (state == PORT_STATE_IN_ALERTING
1914 || state == PORT_STATE_OUT_ALERTING) {
1915 if (p_m_mISDNport->ifport->tout_alerting)
1916 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_alerting, 0);
1919 if (state == PORT_STATE_CONNECT
1920 || state == PORT_STATE_CONNECT_WAITING) {
1921 if (p_m_mISDNport->ifport->tout_connect)
1922 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_connect, 0);
1925 if (state == PORT_STATE_IN_DISCONNECT
1926 || state == PORT_STATE_OUT_DISCONNECT) {
1927 if (p_m_mISDNport->ifport->tout_disconnect)
1928 schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_disconnect, 0);
1932 Port::new_state(state);
1936 /* deletes only if l3id is release, otherwhise it will be triggered then */
1937 static int delete_event(struct lcr_work *work, void *instance, int index)
1939 class Pdss1 *isdnport = (class Pdss1 *)instance;
1941 if (!isdnport->p_m_d_l3id)
1949 * handles all messages from endpoint
1951 /* MESSAGE_INFORMATION */
1952 void Pdss1::message_information(unsigned int epoint_id, int message_id, union parameter *param)
1955 char *display = param->information.display;
1956 char *number = param->information.id;
1957 int max = p_m_mISDNport->ifport->dialmax;
1959 while (number[0]) { /* as long we have something to dial */
1960 if (max > (int)strlen(number) || max == 0)
1961 max = (int)strlen(number);
1963 l3m = create_l3msg();
1964 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
1965 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)number, max);
1966 if ((p_m_d_ntmode || p_m_d_tespecial) && display[0]) {
1967 enc_ie_display(l3m, (unsigned char *)display);
1968 display = (char *)"";
1971 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
1979 void Pdss1::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1982 #ifdef OLD_MT_ASSIGN
1985 int plan, type, screen, present, reason;
1986 int plan2, type2, screen2, present2;
1987 int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
1988 int channel, exclusive;
1989 struct epoint_list *epointlist;
1990 int max = p_m_mISDNport->ifport->dialmax;
1992 /* release if port is blocked */
1993 if (p_m_mISDNport->ifport->block) {
1994 struct lcr_msg *message;
1996 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1997 message->param.disconnectinfo.cause = 27; // temp. unavail.
1998 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1999 message_put(message);
2000 new_state(PORT_STATE_RELEASE);
2001 trigger_work(&p_m_d_delete);
2005 /* copy setup infos to port */
2006 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
2007 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
2008 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
2009 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
2010 /* screen outgoing caller id */
2011 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
2012 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
2013 do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_m_mISDNport->ifport->interface->name);
2015 /* only display at connect state: this case happens if endpoint is in connected mode */
2016 if (p_state==PORT_STATE_CONNECT) {
2017 if (p_type!=PORT_TYPE_DSS1_NT_OUT
2018 && p_type!=PORT_TYPE_DSS1_NT_IN)
2020 if (p_callerinfo.display[0]) {
2021 /* sending information */
2022 l3m = create_l3msg();
2023 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2024 if (p_m_d_ntmode || p_m_d_tespecial)
2025 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2027 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
2032 /* attach only if not already */
2033 epointlist = p_epointlist;
2035 if (epointlist->epoint_id == epoint_id)
2037 epointlist = epointlist->next;
2040 epointlist_new(epoint_id);
2044 if (p_m_b_channel) {
2045 channel = p_m_b_channel;
2046 exclusive = p_m_b_exclusive;
2048 channel = CHANNEL_ANY;
2049 /* nt-port with no channel, not reserverd */
2050 if (!p_m_b_channel && !p_m_b_reserve && p_type==PORT_TYPE_DSS1_NT_OUT)
2051 channel = CHANNEL_NO;
2054 l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_REQ, DIRECTION_OUT);
2055 #ifdef OLD_MT_ASSIGN
2056 /* see MT_ASSIGN notes at do_layer3() */
2058 ret = p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_ASSIGN, 0, NULL);
2059 if (mt_assign_pid == 0 || ret < 0)
2060 p_m_d_l3id = mt_assign_pid;
2063 p_m_d_l3id = request_new_pid(p_m_mISDNport->ml3);
2064 if (p_m_d_l3id == MISDN_PID_NONE)
2067 struct lcr_msg *message;
2069 add_trace("callref", NULL, "no free id");
2071 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2072 message->param.disconnectinfo.cause = 47;
2073 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2074 message_put(message);
2075 new_state(PORT_STATE_RELEASE);
2076 trigger_work(&p_m_d_delete);
2079 #ifdef OLD_MT_ASSIGN
2080 p_m_d_l3id = mt_assign_pid;
2083 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2086 /* preparing setup message */
2087 l3m = create_l3msg();
2088 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_REQ, DIRECTION_OUT);
2089 /* channel information */
2090 if (p_m_d_ntmode || channel != CHANNEL_ANY) /* only omit channel id in te-mode/any channel */
2091 enc_ie_channel_id(l3m, exclusive, channel);
2092 /* caller information */
2094 switch (p_callerinfo.ntype) {
2095 case INFO_NTYPE_UNKNOWN:
2098 case INFO_NTYPE_INTERNATIONAL:
2101 case INFO_NTYPE_NATIONAL:
2104 case INFO_NTYPE_SUBSCRIBER:
2107 default: /* INFO_NTYPE_NOTPRESENT */
2111 switch (p_callerinfo.screen) {
2112 case INFO_SCREEN_USER:
2115 case INFO_SCREEN_USER_VERIFIED_PASSED:
2118 case INFO_SCREEN_USER_VERIFIED_FAILED:
2121 default: /* INFO_SCREEN_NETWORK */
2125 switch (p_callerinfo.present) {
2126 case INFO_PRESENT_ALLOWED:
2129 case INFO_PRESENT_RESTRICTED:
2132 default: /* INFO_PRESENT_NOTAVAIL */
2136 /* caller information 2 */
2138 switch (p_callerinfo.ntype2) {
2139 case INFO_NTYPE_UNKNOWN:
2142 case INFO_NTYPE_INTERNATIONAL:
2145 case INFO_NTYPE_NATIONAL:
2148 case INFO_NTYPE_SUBSCRIBER:
2151 default: /* INFO_NTYPE_NOTPRESENT */
2155 switch (p_callerinfo.screen2) {
2156 case INFO_SCREEN_USER:
2159 case INFO_SCREEN_USER_VERIFIED_PASSED:
2162 case INFO_SCREEN_USER_VERIFIED_FAILED:
2165 default: /* INFO_SCREEN_NETWORK */
2169 switch (p_callerinfo.present2) {
2170 case INFO_PRESENT_ALLOWED:
2173 case INFO_PRESENT_RESTRICTED:
2176 default: /* INFO_PRESENT_NOTAVAIL */
2181 enc_ie_calling_pn(l3m, type, plan, present, screen, (unsigned char *)p_callerinfo.id, type2, plan2, present2, screen2, (unsigned char *)p_callerinfo.id2);
2182 /* dialing information */
2183 if (p_dialinginfo.id[0]) { /* only if we have something to dial */
2184 if (max > (int)strlen(p_dialinginfo.id) || max == 0)
2185 max = (int)strlen(p_dialinginfo.id);
2186 enc_ie_called_pn(l3m, 0, 1, (unsigned char *)p_dialinginfo.id, max);
2187 SCPY(p_m_d_queue, p_dialinginfo.id + max);
2190 if (p_dialinginfo.keypad[0])
2191 enc_ie_keypad(l3m, (unsigned char *)p_dialinginfo.keypad);
2192 /* sending complete */
2193 if (p_dialinginfo.sending_complete)
2194 enc_ie_complete(l3m, 1);
2195 /* sending user-user */
2196 if (param->setup.useruser.len) {
2197 enc_ie_useruser(l3m, param->setup.useruser.protocol, param->setup.useruser.data, param->setup.useruser.len);
2199 /* redirecting number */
2201 switch (p_redirinfo.ntype) {
2202 case INFO_NTYPE_UNKNOWN:
2205 case INFO_NTYPE_INTERNATIONAL:
2208 case INFO_NTYPE_NATIONAL:
2211 case INFO_NTYPE_SUBSCRIBER:
2214 default: /* INFO_NTYPE_NOTPRESENT */
2218 switch (p_redirinfo.screen) {
2219 case INFO_SCREEN_USER:
2222 case INFO_SCREEN_USER_VERIFIED_PASSED:
2225 case INFO_SCREEN_USER_VERIFIED_FAILED:
2228 default: /* INFO_SCREE_NETWORK */
2232 switch (p_redirinfo.reason) {
2233 case INFO_REDIR_BUSY:
2236 case INFO_REDIR_NORESPONSE:
2239 case INFO_REDIR_UNCONDITIONAL:
2242 case INFO_REDIR_CALLDEFLECT:
2245 case INFO_REDIR_OUTOFORDER:
2248 default: /* INFO_REDIR_UNKNOWN */
2252 switch (p_redirinfo.present) {
2253 case INFO_PRESENT_ALLOWED:
2256 case INFO_PRESENT_RESTRICTED:
2259 default: /* INFO_PRESENT_NOTAVAIL */
2263 /* sending redirecting number only in ntmode */
2264 if (type >= 0 && (p_m_d_ntmode || p_m_d_tespecial))
2265 enc_ie_redir_nr(l3m, type, plan, present, screen, reason, (unsigned char *)p_redirinfo.id);
2266 /* bearer capability */
2267 //printf("hlc=%d\n",p_capainfo.hlc);
2269 capability = p_capainfo.bearer_capa;
2270 mode = p_capainfo.bearer_mode;
2271 rate = (mode==INFO_BMODE_CIRCUIT)?0x10:0x00;
2272 switch (p_capainfo.bearer_info1) {
2273 case INFO_INFO1_NONE:
2277 user = p_capainfo.bearer_info1 & 0x7f;
2280 enc_ie_bearer(l3m, coding, capability, mode, rate, -1, user);
2282 if (p_capainfo.hlc) {
2286 hlc = p_capainfo.hlc & 0x7f;
2288 if (p_capainfo.exthlc)
2289 exthlc = p_capainfo.exthlc & 0x7f;
2290 enc_ie_hlc(l3m, coding, interpretation, presentation, hlc, exthlc);
2294 if (p_callerinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2295 enc_ie_display(l3m, (unsigned char *)p_callerinfo.display);
2296 /* nt-mode: CNIP (calling name identification presentation) */
2297 // if (p_callerinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2298 // enc_facility_centrex(&setup->FACILITY, dmsg, (unsigned char *)p_callerinfo.name, 1);
2301 /* send setup message now */
2302 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SETUP, p_m_d_l3id, l3m);
2304 new_state(PORT_STATE_OUT_SETUP);
2307 /* MESSAGE_FACILITY */
2308 void Pdss1::message_facility(unsigned int epoint_id, int message_id, union parameter *param)
2312 /* facility will not be sent to external lines */
2313 if (!p_m_d_ntmode && !p_m_d_tespecial)
2316 /* sending facility */
2317 l3m = create_l3msg();
2318 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2319 enc_ie_facility(l3m, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len);
2321 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
2325 void Pdss1::message_3pty(unsigned int epoint_id, int message_id, union parameter *param)
2328 unsigned char fac_ie[256];
2329 struct asn1_parm fac;
2331 /* encode 3PTY facility */
2332 memset(&fac, 0, sizeof(fac));
2334 if (param->threepty.result) {
2335 fac.comp = CompReturnResult;
2336 fac.u.retResult.invokeId = param->threepty.invoke_id;
2337 fac.u.retResult.operationValuePresent = 1;
2338 if (param->threepty.begin)
2339 fac.u.retResult.operationValue = Fac_Begin3PTY;
2340 if (param->threepty.end)
2341 fac.u.retResult.operationValue = Fac_End3PTY;
2343 if (param->threepty.error) {
2344 fac.comp = CompReturnError;
2345 fac.u.retError.invokeId = param->threepty.invoke_id;
2346 fac.u.retError.errorValue = FacError_Gen_InvalidCallState;
2348 encodeFac(fac_ie, &fac);
2350 /* sending facility */
2351 l3m = create_l3msg();
2352 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2353 enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]);
2355 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
2358 void Pdss1::enc_ie_facility_ect(l3_msg *l3m, struct param_transfer *transfer)
2360 unsigned char fac_ie[256];
2361 struct asn1_parm fac;
2363 /* encode ECT facility */
2364 memset(&fac, 0, sizeof(fac));
2366 if (transfer->result) {
2367 fac.comp = CompReturnResult;
2368 fac.u.retResult.invokeId = transfer->invoke_id;
2369 fac.u.retResult.operationValuePresent = 1;
2370 fac.u.retResult.operationValue = Fac_EctExecute;
2372 if (transfer->error) {
2373 fac.comp = CompReturnError;
2374 fac.u.retError.invokeId = transfer->invoke_id;
2375 fac.u.retError.errorValue = FacError_Gen_InvalidCallState;
2377 encodeFac(fac_ie, &fac);
2379 enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]);
2382 /* MESSAGE_TRANSFER */
2383 void Pdss1::message_transfer(unsigned int epoint_id, int message_id, union parameter *param)
2387 /* sending facility */
2388 l3m = create_l3msg();
2389 l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
2390 enc_ie_facility_ect(l3m, ¶m->transfer);
2392 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
2395 /* MESSAGE_NOTIFY */
2396 void Pdss1::message_notify(unsigned int epoint_id, int message_id, union parameter *param)
2400 int plan = 0, type = -1, present = 0;
2402 if (p_m_mISDNport->ifport->nonotify) {
2403 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
2404 add_trace("info", NULL, "blocked by config");
2409 // printf("if = %d\n", param->notifyinfo.notify);
2410 if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
2411 notify = param->notifyinfo.notify & 0x7f;
2416 switch (param->notifyinfo.ntype) {
2417 case INFO_NTYPE_UNKNOWN:
2420 case INFO_NTYPE_INTERNATIONAL:
2423 case INFO_NTYPE_NATIONAL:
2426 case INFO_NTYPE_SUBSCRIBER:
2429 default: /* INFO_NTYPE_UNKNOWN */
2433 switch (param->notifyinfo.present) {
2434 case INFO_PRESENT_ALLOWED:
2437 case INFO_PRESENT_RESTRICTED:
2440 default: /* INFO_PRESENT_NOTAVAIL */
2446 if (notify<0 && !param->notifyinfo.display[0]) {
2447 /* nothing to notify, nothing to display */
2452 if (p_state!=PORT_STATE_CONNECT && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING) {
2453 /* queue notification */
2454 if (p_m_d_notify_pending)
2455 message_free(p_m_d_notify_pending);
2456 p_m_d_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
2457 memcpy(&p_m_d_notify_pending->param, param, sizeof(union parameter));
2459 /* sending notification */
2460 l3m = create_l3msg();
2461 l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
2462 enc_ie_notify(l3m, notify);
2463 /* sending redirection number only in ntmode */
2464 if (type >= 0 && (p_m_d_ntmode || p_m_d_tespecial))
2465 enc_ie_redir_dn(l3m, type, plan, present, (unsigned char *)param->notifyinfo.id);
2466 if (param->notifyinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2467 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2469 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_NOTIFY, p_m_d_l3id, l3m);
2471 } else if (p_m_d_ntmode || p_m_d_tespecial) {
2472 /* sending information */
2473 l3m = create_l3msg();
2474 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
2475 enc_ie_display(l3m, (unsigned char *)param->notifyinfo.display);
2477 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
2481 /* MESSAGE_OVERLAP */
2482 void Pdss1::message_overlap(unsigned int epoint_id, int message_id, union parameter *param)
2486 /* in case of sending complete, we proceed */
2487 if (p_dialinginfo.sending_complete) {
2488 PDEBUG(DEBUG_ISDN, "sending proceeding instead of setup_acknowledge, because address is complete.\n");
2489 message_proceeding(epoint_id, message_id, param);
2493 /* sending setup_acknowledge */
2494 l3m = create_l3msg();
2495 l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_ACKNOWLEDGE_REQ, DIRECTION_OUT);
2496 /* channel information */
2497 if (p_state == PORT_STATE_IN_SETUP)
2498 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2499 /* progress information */
2500 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2501 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2502 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2503 if (p_m_mISDNport->tones)
2504 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2506 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SETUP_ACKNOWLEDGE, p_m_d_l3id, l3m);
2508 new_state(PORT_STATE_IN_OVERLAP);
2511 /* MESSAGE_PROCEEDING */
2512 void Pdss1::message_proceeding(unsigned int epoint_id, int message_id, union parameter *param)
2516 /* sending proceeding */
2517 l3m = create_l3msg();
2518 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2519 /* channel information */
2520 if (p_state == PORT_STATE_IN_SETUP)
2521 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2522 /* progress information */
2523 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2524 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2525 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2526 if (p_m_mISDNport->tones)
2527 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2529 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2531 new_state(PORT_STATE_IN_PROCEEDING);
2534 /* MESSAGE_ALERTING */
2535 void Pdss1::message_alerting(unsigned int epoint_id, int message_id, union parameter *param)
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);
2546 /* progress information */
2547 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2548 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2549 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2550 if (p_m_mISDNport->tones)
2551 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2553 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2554 new_state(PORT_STATE_IN_PROCEEDING);
2557 /* sending alerting */
2558 l3m = create_l3msg();
2559 l1l2l3_trace_header(p_m_mISDNport, this, L3_ALERTING_REQ, DIRECTION_OUT);
2560 /* channel information */
2561 if (p_state == PORT_STATE_IN_SETUP)
2562 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2563 /* progress information */
2564 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2565 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2566 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2567 if (p_m_mISDNport->tones)
2568 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2570 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_ALERTING, p_m_d_l3id, l3m);
2572 new_state(PORT_STATE_IN_ALERTING);
2575 /* MESSAGE_CONNECT */
2576 void Pdss1::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
2579 int type, plan, present, screen;
2580 time_t current_time;
2582 /* NT-MODE in setup state we must send PROCEEDING first */
2583 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
2584 /* sending proceeding */
2585 l3m = create_l3msg();
2586 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2587 /* channel information */
2588 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2590 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2591 new_state(PORT_STATE_IN_PROCEEDING);
2594 /* copy connected information */
2595 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
2596 /* screen outgoing caller id */
2597 do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface->name);
2599 set_display(p_connectinfo.display);
2601 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) {
2602 /* connect command only possible in setup, proceeding or alerting state */
2606 /* preparing connect message */
2607 l3m = create_l3msg();
2608 l1l2l3_trace_header(p_m_mISDNport, this, L3_CONNECT_REQ, DIRECTION_OUT);
2609 /* connect information */
2611 switch (p_connectinfo.ntype) {
2612 case INFO_NTYPE_UNKNOWN:
2615 case INFO_NTYPE_INTERNATIONAL:
2618 case INFO_NTYPE_NATIONAL:
2621 case INFO_NTYPE_SUBSCRIBER:
2624 default: /* INFO_NTYPE_NOTPRESENT */
2628 switch (param->connectinfo.screen) {
2629 case INFO_SCREEN_USER:
2632 case INFO_SCREEN_USER_VERIFIED_PASSED:
2635 case INFO_SCREEN_USER_VERIFIED_FAILED:
2638 default: /* INFO_SCREE_NETWORK */
2642 switch (p_connectinfo.present) {
2643 case INFO_PRESENT_ALLOWED:
2646 case INFO_PRESENT_RESTRICTED:
2649 default: /* INFO_PRESENT_NOTAVAIL */
2654 enc_ie_connected_pn(l3m, type, plan, present, screen, (unsigned char *)p_connectinfo.id);
2656 if (p_connectinfo.display[0] && (p_m_d_ntmode || p_m_d_tespecial))
2657 enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
2658 /* nt-mode: CONP (connected name identification presentation) */
2659 // if (p_connectinfo.name[0] && (p_m_d_ntmode || p_m_d_tespecial))
2660 // enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
2662 if (p_m_d_ntmode || p_m_d_tespecial) {
2663 time(¤t_time);
2664 enc_ie_date(l3m, current_time, p_settings.no_seconds);
2667 /* finally send message */
2668 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CONNECT, p_m_d_l3id, l3m);
2671 new_state(PORT_STATE_CONNECT);
2673 new_state(PORT_STATE_CONNECT_WAITING);
2677 /* MESSAGE_DISCONNECT */
2678 void Pdss1::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
2681 struct lcr_msg *message;
2684 /* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
2685 // if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
2686 if (/* ||*/ p_state==PORT_STATE_OUT_SETUP) {
2687 /* sending release to endpoint */
2688 while(p_epointlist) {
2689 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
2690 memcpy(&message->param, param, sizeof(union parameter));
2691 message_put(message);
2693 free_epointlist(p_epointlist);
2695 /* sending release */
2696 l3m = create_l3msg();
2697 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_COMPLETE_REQ, DIRECTION_OUT);
2699 enc_ie_cause(l3m, (!p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_REMOTE:param->disconnectinfo.location, param->disconnectinfo.cause);
2701 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
2702 new_state(PORT_STATE_RELEASE);
2703 trigger_work(&p_m_d_delete);
2707 /* workarround: NT-MODE in setup state we must send PROCEEDING first to make it work */
2708 if (p_state==PORT_STATE_IN_SETUP) {
2709 /* sending proceeding */
2710 l3m = create_l3msg();
2711 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2712 /* channel information */
2713 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2714 /* progress information */
2715 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2716 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2717 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2718 if (p_m_mISDNport->tones)
2719 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2721 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2722 new_state(PORT_STATE_IN_PROCEEDING);
2725 /* sending disconnect */
2726 l3m = create_l3msg();
2727 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
2728 /* progress information */
2729 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2730 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2731 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2732 if (p_m_mISDNport->tones)
2733 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2735 enc_ie_cause(l3m, (!p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_REMOTE:param->disconnectinfo.location, param->disconnectinfo.cause);
2737 if (param->disconnectinfo.transfer.result) {
2738 enc_ie_facility_ect(l3m, ¶m->disconnectinfo.transfer);
2741 if (param->disconnectinfo.display[0])
2742 p = param->disconnectinfo.display;
2743 if (p) if (*p && (p_m_d_ntmode || p_m_d_tespecial))
2744 enc_ie_display(l3m, (unsigned char *)p);
2746 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_DISCONNECT, p_m_d_l3id, l3m);
2747 new_state(PORT_STATE_OUT_DISCONNECT);
2750 /* MESSAGE_RELEASE */
2751 void Pdss1::message_release(unsigned int epoint_id, int message_id, union parameter *param)
2757 * if we are on incoming call setup, we may reject by sending a release_complete
2758 * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
2760 if (p_state==PORT_STATE_IN_SETUP
2761 || p_state==PORT_STATE_OUT_SETUP) {
2762 //#warning remove me
2763 //PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
2764 /* sending release complete */
2765 l3m = create_l3msg();
2766 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
2768 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2770 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
2771 new_state(PORT_STATE_RELEASE);
2773 free_epointid(epoint_id);
2774 // wait for callref to be released
2778 * we may only release during incoming disconnect state.
2779 * this means that the endpoint doesnt require audio anymore
2781 if (p_state == PORT_STATE_IN_DISCONNECT
2782 || p_state == PORT_STATE_OUT_DISCONNECT
2783 || param->disconnectinfo.force) {
2784 /* sending release */
2785 l3m = create_l3msg();
2786 l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
2788 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2790 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
2791 new_state(PORT_STATE_RELEASE);
2793 free_epointid(epoint_id);
2794 // wait for callref to be released
2800 wirklich erst proceeding?:
2801 /* NT-MODE in setup state we must send PROCEEDING first */
2802 if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
2803 CALL_PROCEEDING_t *proceeding;
2805 /* sending proceeding */
2806 l3m = create_l3msg();
2807 l1l2l3_trace_header(p_m_mISDNport, this, L3_PROCEEDING_REQ, DIRECTION_OUT);
2808 /* channel information */
2809 enc_ie_channel_id(l3m, 1, p_m_b_channel);
2810 /* progress information */
2811 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2812 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2813 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2814 if (p_m_mISDNport->tones)
2815 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2817 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_CALL_PROCEEDING, p_m_d_l3id, l3m);
2821 /* sending disconnect */
2822 l3m = create_l3msg();
2823 l1l2l3_trace_header(p_m_mISDNport, this, L3_DISCONNECT_REQ, DIRECTION_OUT);
2824 /* progress information */
2825 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2826 || p_capainfo.bearer_capa==INFO_BC_AUDIO
2827 || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2828 if (p_m_mISDNport->tones)
2829 enc_ie_progress(l3m, 0, (p_m_d_ntmode)?1:5, 8);
2831 enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2833 if (param->disconnectinfo.display[0])
2834 p = param->disconnectinfo.display;
2835 if (p) if (*p && (p_m_d_ntmode || p_m_d_tespecial))
2836 enc_ie_display(l3m, (unsigned char *)p);
2838 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_DISCONNECT, p_m_d_l3id, l3m);
2839 new_state(PORT_STATE_OUT_DISCONNECT);
2841 free_epointid(epoint_id);
2842 // wait for release and callref to be released
2843 //#warning remove me
2844 //PDEBUG(DEBUG_LOG, "JOLLY sending disconnect %d\n", p_serial);
2849 * endpoint sends messages to the port
2851 int Pdss1::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
2853 if (PmISDN::message_epoint(epoint_id, message_id, param))
2856 switch(message_id) {
2857 case MESSAGE_INFORMATION: /* overlap dialing */
2858 if (p_type==PORT_TYPE_DSS1_NT_OUT
2859 && p_state!=PORT_STATE_OUT_OVERLAP
2860 && p_state!=PORT_STATE_CONNECT
2861 && p_state!=PORT_STATE_OUT_DISCONNECT
2862 && p_state!=PORT_STATE_IN_DISCONNECT) {
2865 if (p_type==PORT_TYPE_DSS1_TE_OUT
2866 && p_state!=PORT_STATE_OUT_OVERLAP
2867 && p_state!=PORT_STATE_OUT_PROCEEDING
2868 && p_state!=PORT_STATE_OUT_ALERTING
2869 && p_state!=PORT_STATE_CONNECT
2870 && p_state!=PORT_STATE_OUT_DISCONNECT
2871 && p_state!=PORT_STATE_IN_DISCONNECT) {
2874 if ((p_type==PORT_TYPE_DSS1_NT_IN || p_type==PORT_TYPE_DSS1_TE_IN)
2875 && p_state!=PORT_STATE_IN_OVERLAP
2876 && p_state!=PORT_STATE_IN_PROCEEDING
2877 && p_state!=PORT_STATE_IN_ALERTING
2878 && p_state!=PORT_STATE_CONNECT
2879 && p_state!=PORT_STATE_CONNECT_WAITING
2880 && p_state!=PORT_STATE_OUT_DISCONNECT
2881 && p_state!=PORT_STATE_IN_DISCONNECT) {
2884 message_information(epoint_id, message_id, param);
2887 case MESSAGE_SETUP: /* dial-out command received from epoint */
2888 if (p_state!=PORT_STATE_IDLE
2889 && p_state!=PORT_STATE_CONNECT) {
2890 PERROR("Pdss1(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
2893 if (p_epointlist && p_state==PORT_STATE_IDLE)
2894 FATAL("Pdss1(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
2895 message_setup(epoint_id, message_id, param);
2898 case MESSAGE_NOTIFY: /* display and notifications */
2899 message_notify(epoint_id, message_id, param);
2902 case MESSAGE_FACILITY: /* facility message */
2903 message_facility(epoint_id, message_id, param);
2906 case MESSAGE_3PTY: /* begin result message */
2907 message_3pty(epoint_id, message_id, param);
2910 case MESSAGE_TRANSFER: /* begin result message */
2911 message_transfer(epoint_id, message_id, param);
2914 case MESSAGE_OVERLAP: /* more information is needed */
2915 if (p_state!=PORT_STATE_IN_SETUP) {
2918 message_overlap(epoint_id, message_id, param);
2921 case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
2922 if (p_state!=PORT_STATE_IN_SETUP
2923 && p_state!=PORT_STATE_IN_OVERLAP) {
2926 message_proceeding(epoint_id, message_id, param);
2927 if (p_m_d_notify_pending) {
2928 /* send pending notify message during connect */
2929 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2930 message_free(p_m_d_notify_pending);
2931 p_m_d_notify_pending = NULL;
2935 case MESSAGE_ALERTING: /* call of endpoint is ringing */
2936 if (p_state!=PORT_STATE_IN_SETUP
2937 && p_state!=PORT_STATE_IN_OVERLAP
2938 && p_state!=PORT_STATE_IN_PROCEEDING) {
2941 message_alerting(epoint_id, message_id, param);
2942 if (p_m_d_notify_pending) {
2943 /* send pending notify message during connect */
2944 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2945 message_free(p_m_d_notify_pending);
2946 p_m_d_notify_pending = NULL;
2950 case MESSAGE_CONNECT: /* call of endpoint is connected */
2951 if (p_state!=PORT_STATE_IN_SETUP
2952 && p_state!=PORT_STATE_IN_OVERLAP
2953 && p_state!=PORT_STATE_IN_PROCEEDING
2954 && p_state!=PORT_STATE_IN_ALERTING
2955 && !(p_state==PORT_STATE_CONNECT && p_m_d_ntmode)) {
2958 message_connect(epoint_id, message_id, param);
2959 if (p_m_d_notify_pending) {
2960 /* send pending notify message during connect */
2961 message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2962 message_free(p_m_d_notify_pending);
2963 p_m_d_notify_pending = NULL;
2967 case MESSAGE_DISCONNECT: /* call has been disconnected */
2968 if (p_state!=PORT_STATE_IN_SETUP
2969 && p_state!=PORT_STATE_IN_OVERLAP
2970 && p_state!=PORT_STATE_IN_PROCEEDING
2971 && p_state!=PORT_STATE_IN_ALERTING
2972 && p_state!=PORT_STATE_OUT_SETUP
2973 && p_state!=PORT_STATE_OUT_OVERLAP
2974 && p_state!=PORT_STATE_OUT_PROCEEDING
2975 && p_state!=PORT_STATE_OUT_ALERTING
2976 && p_state!=PORT_STATE_CONNECT
2977 && p_state!=PORT_STATE_CONNECT_WAITING) {
2980 message_disconnect(epoint_id, message_id, param);
2983 case MESSAGE_RELEASE: /* release isdn port */
2984 if (p_state==PORT_STATE_RELEASE) {
2987 message_release(epoint_id, message_id, param);
2991 PERROR("Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message_id);
3000 * data from isdn-stack (layer-3) to pbx (port class)
3002 int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
3008 PDEBUG(DEBUG_ISDN, "cmd(0x%x) pid(0x%x)\n", cmd, pid);
3011 PDEBUG(DEBUG_ISDN, "ignoring dummy process from phone.\n");
3015 /* find Port object of type ISDN */
3019 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
3020 pdss1 = (class Pdss1 *)port;
3021 /* check out correct stack and id */
3022 if (pdss1->p_m_mISDNport == mISDNport) {
3023 if (pdss1->p_m_d_l3id & MISDN_PID_CR_FLAG) {
3024 /* local callref, so match value only */
3025 if ((pdss1->p_m_d_l3id & MISDN_PID_CRVAL_MASK) == (pid & MISDN_PID_CRVAL_MASK))
3028 /* remote callref, ref + channel id */
3029 if (pdss1->p_m_d_l3id == pid)
3037 /* aktueller prozess */
3039 if (cmd == MT_ASSIGN) {
3040 /* stack gives us new layer 3 id (during connect) */
3041 l1l2l3_trace_header(mISDNport, pdss1, L3_NEW_L3ID_IND, DIRECTION_IN);
3042 add_trace("callref", "old", "0x%x", pdss1->p_m_d_l3id);
3043 /* nt-library now gives us a new id via CC_SETUP_CONFIRM */
3044 if ((pdss1->p_m_d_l3id&MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER)
3045 PERROR(" strange setup-procid 0x%x\n", pdss1->p_m_d_l3id);
3046 pdss1->p_m_d_l3id = pid;
3047 if (port->p_state == PORT_STATE_CONNECT)
3048 pdss1->p_m_d_ces = pid >> 16;
3049 add_trace("callref", "new", "0x%x", pdss1->p_m_d_l3id);
3053 /* if process id is master process, but a child disconnects */
3054 if (mISDNport->ntmode
3055 && (pid & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3056 && (pdss1->p_m_d_l3id & MISDN_PID_CRTYPE_MASK) == MISDN_PID_MASTER) {
3057 if (cmd == MT_DISCONNECT
3058 || cmd == MT_RELEASE) {
3059 /* send special indication for child disconnect */
3060 pdss1->disconnect_ind_i(cmd, pid, l3m);
3063 if (cmd == MT_RELEASE_COMPLETE)
3066 /* if we have child pid and got different child pid message, ignore */
3067 if (mISDNport->ntmode
3068 && (pid & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3069 && (pdss1->p_m_d_l3id & MISDN_PID_CRTYPE_MASK) != MISDN_PID_MASTER
3070 && pid != pdss1->p_m_d_l3id)
3073 /* process message */
3074 pdss1->message_isdn(cmd, pid, l3m);
3081 /* creating port object, transparent until setup with hdlc */
3082 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3083 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, mISDNport->ifport->interface, 0, 0, B_MODE_TRANSPARENT)))
3085 FATAL("Cannot create Port instance.\n");
3086 pdss1->message_isdn(cmd, pid, l3m);
3090 /* creating port object, transparent until setup with hdlc */
3091 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3092 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, mISDNport->ifport->interface, 0, 0, B_MODE_TRANSPARENT)))
3093 FATAL("Cannot create Port instance.\n");
3094 pdss1->message_isdn(cmd, pid, l3m);
3098 PDEBUG(DEBUG_ISDN, "unused call ref released (l3id=0x%x)\n", pid);
3101 case MT_RELEASE_COMPLETE:
3102 PERROR("must be ignored by stack, not sent to app\n");
3106 // facility als broadcast
3110 // L2 became idle - we could sent a MT_L2RELEASE if we are the L2 master
3111 PDEBUG(DEBUG_ISDN, "Got L2 idle\n");
3115 PERROR("unhandled message: cmd(0x%x) pid(0x%x)\n", cmd, pid);
3118 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT) {
3119 pdss1 = (class Pdss1 *)port;
3120 /* check out correct stack */
3121 if (pdss1->p_m_mISDNport == mISDNport)
3122 /* check out correct id */
3123 PERROR("unhandled message: pid=%x is not associated with port-dinfo=%x\n", pid, pdss1->p_m_d_l3id);
3132 void Pdss1::set_display(const char *text)
3136 /* only display at connect state */
3137 if (p_state == PORT_STATE_CONNECT)
3139 /* sending information */
3140 l3m = create_l3msg();
3141 l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
3142 if (p_m_d_ntmode || p_m_d_tespecial)
3143 enc_ie_display(l3m, (unsigned char *)text);
3145 p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);