backup
[lcr.git] / dss1.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN dss1                                                                **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include "main.h"
17 #include <unistd.h>
18 #include <poll.h>
19 #include <errno.h>
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 extern "C" {
25 #include <net_l2.h>
26 }
27
28 //#define CENTREX
29
30 #include "q931.h"
31 #include "ie.cpp"
32
33
34 /*
35  * constructor
36  */
37 Pdss1::Pdss1(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : PmISDN(type, mISDNport, portname, settings, channel, exclusive)
38 {
39         p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN:INFO_ITYPE_ISDN_EXTENSION;
40         p_m_d_ntmode = mISDNport->ntmode;
41         p_m_d_l3id = 0;
42         p_m_d_ces = -1;
43         p_m_d_queue = NULL;
44         p_m_d_notify_pending = NULL;
45         p_m_d_collect_cause = CAUSE_NOUSER;
46         p_m_d_collect_location = LOCATION_PRIVATE_LOCAL;
47
48
49         PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, %s port #%d\n", portname, mISDNport->use, (mISDNport->ntmode)?"NT":"TE", p_m_portnum);
50 }
51
52
53 /*
54  * destructor
55  */
56 Pdss1::~Pdss1()
57 {
58         /* remove queued message */
59         if (p_m_d_queue)
60                 message_free(p_m_d_queue);
61
62         if (p_m_d_notify_pending)
63                 message_free(p_m_d_notify_pending);
64
65         /* check how many processes are left */
66         if (p_m_d_ntmode == 1)
67         {
68                 if (p_m_mISDNport->nst.layer3->proc)
69                         PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). WARNING: There is still a layer 3 process left. Ignore this, if currently are other calls. This message is not an error!\n", p_name);
70         }
71 }
72
73
74 /*
75  * create layer 3 message
76  */
77 static msg_t *create_l3msg(int prim, int mt, int dinfo, int size, int ntmode)
78 {
79         int i = 0;
80         msg_t *dmsg;
81         Q931_info_t *qi;
82         iframe_t *frm;
83
84         if (!ntmode)
85                 size = sizeof(Q931_info_t)+2;
86
87         while(i < 10)
88         {
89                 if (ntmode)
90                 {
91                         dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
92                         if (dmsg)
93                         {
94                                 return(dmsg);
95                         }
96                 } else
97                 {
98                         dmsg = alloc_msg(size+256+mISDN_HEADER_LEN+DEFAULT_HEADROOM);
99                         if (dmsg)
100                         {
101                                 memset(msg_put(dmsg,size+mISDN_HEADER_LEN), 0, size+mISDN_HEADER_LEN);
102                                 frm = (iframe_t *)dmsg->data;
103                                 frm->prim = prim;
104                                 frm->dinfo = dinfo;
105                                 qi = (Q931_info_t *)(dmsg->data + mISDN_HEADER_LEN);
106                                 qi->type = mt;
107                                 return(dmsg);
108                         }
109                 }
110
111                 if (!i)
112                         PERROR("cannot allocate memory, trying again...\n");
113                 i++;
114                 usleep(50000);
115         }
116         PERROR("cannot allocate memory, system overloaded.\n");
117         exit(-1);
118 }
119
120 msg_t *create_l2msg(int prim, int dinfo, int size) /* NT only */
121 {
122         int i = 0;
123         msg_t *dmsg;
124
125         while(i < 10)
126         {
127                 dmsg = prep_l3data_msg(prim, dinfo, size, 256, NULL);
128                 if (dmsg)
129                         return(dmsg);
130
131                 if (!i)
132                         PERROR("cannot allocate memory, trying again...\n");
133                 i++;
134                 usleep(50000);
135         }
136         PERROR("cannot allocate memory, system overloaded.\n");
137         exit(-1);
138 }
139
140 /* isdn messaging */
141 static struct isdn_message {
142         char *name;
143         unsigned long value;
144 } isdn_message[] = {
145         {"TIMEOUT", CC_TIMEOUT},
146         {"SETUP", CC_SETUP},
147         {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
148         {"PROCEEDING", CC_PROCEEDING},
149         {"ALERTING", CC_ALERTING},
150         {"CONNECT", CC_CONNECT},
151         {"CONNECT RES", CC_CONNECT},
152         {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
153         {"DISCONNECT", CC_DISCONNECT},
154         {"RELEASE", CC_RELEASE},
155         {"RELEASE_COMP", CC_RELEASE_COMPLETE},
156         {"INFORMATION", CC_INFORMATION},
157         {"PROGRESS", CC_PROGRESS},
158         {"NOTIFY", CC_NOTIFY},
159         {"SUSPEND", CC_SUSPEND},
160         {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
161         {"SUSPEND_REJ", CC_SUSPEND_REJECT},
162         {"RESUME", CC_RESUME},
163         {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
164         {"RESUME_REJ", CC_RESUME_REJECT},
165         {"HOLD", CC_HOLD},
166         {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
167         {"HOLD_REJ", CC_HOLD_REJECT},
168         {"RETRIEVE", CC_RETRIEVE},
169         {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
170         {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
171         {"FACILITY", CC_FACILITY},
172         {"STATUS", CC_STATUS},
173         {"RESTART", CC_RESTART},
174         {"RELEASE_CR", CC_RELEASE_CR},
175         {"NEW_CR", CC_NEW_CR},
176
177         {NULL, 0},
178 };
179
180 static char *isdn_prim[4] = {
181         " REQUEST",
182         " CONFIRM",
183         " INDICATION",
184         " RESPONSE",
185 };
186
187
188 /*
189  * isdn trace header
190  */
191 void Pdss1::l3_trace_header(unsigned long prim, int direction_out)
192 {
193         int i;
194         char msgtext[64] = "<<UNKNOWN MESSAGE>>";
195
196         /* select message and primitive text */
197         i = 0;
198         while(isdn_message[i].name)
199         {
200                 if (isdn_message[i].value == (prim&0xffffff00))
201                 {
202                         SCPY(msgtext, isdn_message[i].name);
203                         break;
204                 }
205                 i++;
206         }
207         SCAT(msgtext, isdn_prim[prim&0x00000003]);
208
209         /* add direction */
210         if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
211         {
212                 if (p_m_ntmode)
213                 {
214                         if (direction == DIRECTION_OUT)
215                                 SCAT(msgtext, " N->U");
216                         else
217                                 SCAT(msgtext, " N<-U");
218                 } else
219                 {
220                         if (direction == DIRECTION_OUT)
221                                 SCAT(msgtext, " U->N");
222                         else
223                                 SCAT(msgtext, " U<-N");
224                 }
225         }
226
227         /* init trace with given values */
228         start_trace(p_m_mISDNport->portnum,
229                     p_m_mISDNport->ifport->interface,
230                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
231                     p_dialinginfo.number,
232                     direction,
233                     CATEGORY_L3,
234                     msgtext);
235 }
236
237
238 /*
239  * if we received a first reply to the setup message,
240  * we will check if we have now channel information 
241  * return: <0: error, call is released, -cause is given
242  *          0: ok, nothing to do
243  */
244 int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int exclusive)
245 {
246         int ret;
247         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
248         RELEASE_COMPLETE_t *release_complete;
249         msg_t *dmsg;
250
251         /* correct exclusive to 0, if no explicit channel was given */
252         if (exclusive<0 || channel<=0)
253                 exclusive = 0;
254         
255         /* select scenario */
256         if (p_m_b_channel && p_m_b_exclusive)
257         {
258                 /*** we gave an exclusive channel (or if we are done) ***/
259
260                 /* if not first reply, we are done */
261                 if (p_state != PORT_STATE_OUT_SETUP)
262                         return(0);
263
264                 start_trace(p_m_mISDNport->portnum,
265                             p_m_mISDNport->ifport->interface,
266                             nationalize(p_callerinfo.id, p_callerinfo.ntype),
267                             p_dialinginfo.number,
268                             DIRECTION_OUT,
269                             CATEGORY_CH,
270                             "CHANNEL SELECTION (first reply to setup)");
271                 add_trace("channel", "request", "%d (forced)", p_m_b_channel);
272                 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
273
274                 /* if give channel not accepted or not equal */
275                 if (channel!=-1 && p_m_b_channel!=channel)
276                 {
277                         add_trace("conclusion", NULL, "forced channel not accepted");
278                         end_trace();
279                         ret = -44;
280                         goto channelerror;
281                 }
282
283                 add_trace("conclusion", NULL, "channel was accepted");
284                 add_trace("connect", "channel", "%d", p_m_b_channel);
285                 end_trace();
286
287                 /* activate our exclusive channel */
288                 bchannel_activate(p_m_mISDNport, p_m_b_index);
289         } else
290         if (p_m_b_channel)
291         {
292                 /*** we gave a non-exclusive channel ***/
293
294                 /* if not first reply, we are done */
295                 if (p_state != PORT_STATE_OUT_SETUP)
296                         return(0);
297
298                 start_trace(p_m_mISDNport->portnum,
299                             p_m_mISDNport->ifport->interface,
300                             nationalize(p_callerinfo.id, p_callerinfo.ntype),
301                             p_dialinginfo.number,
302                             DIRECTION_OUT,
303                             CATEGORY_CH,
304                             "CHANNEL SELECTION (first reply to setup)");
305                 add_trace("channel", "request", "%d (suggest)", p_m_b_channel);
306                 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
307
308                 /* if channel was accepted as given */
309                 if (channel==-1 || p_m_b_channel==channel)
310                 {
311                         add_trace("conclusion", NULL, "channel was accepted as given");
312                         add_trace("connect", "channel", "%d", p_m_b_channel);
313                         end_trace();
314                         p_m_b_exclusive = 1; // we are done
315                         bchannel_activate(p_m_mISDNport, p_m_b_index);
316                         return(0);
317                 }
318
319                 /* if channel value is faulty */
320                 if (channel <= 0)
321                 {
322                         add_trace("conclusion", NULL, "illegal reply");
323                         end_trace();
324                         ret = -111; // protocol error
325                         goto channelerror;
326                 }
327
328                 /* if channel was not accepted, try to get it */
329                 PDEBUG(DEBUG_BCHANNEL, "- our suggested channel %d was not accepted, but %d was given.\n", p_m_b_channel, channel);
330                 ret = seize_bchannel(channel, 1); // exclusively
331                 add_trace("channel", "available", ret<0?"no":"yes");
332                 if (ret < 0)
333                 {
334                         add_trace("conclusion", NULL, "replied channel not available");
335                         end_trace();
336                         PDEBUG(DEBUG_BCHANNEL, "- the replied channel %d is not available (cause %d).\n", channel, -ret);
337                         goto channelerror;
338                 }
339                 add_trace("conclusion", NULL, "replied channel accepted");
340                 add_trace("connect", "channel", "%d", p_m_b_channel);
341                 end_trace();
342
343                 /* activate channel given by remote */
344                 bchannel_activate(p_m_mISDNport, p_m_b_index);
345         } else
346         if (p_m_b_reserve)
347         {
348                 /*** we sent 'any channel acceptable' ***/
349
350                 /* if not first reply, we are done */
351                 if (p_state != PORT_STATE_OUT_SETUP)
352                         return(0);
353
354                 start_trace(p_m_mISDNport->portnum,
355                             p_m_mISDNport->ifport->interface,
356                             nationalize(p_callerinfo.id, p_callerinfo.ntype),
357                             p_dialinginfo.number,
358                             DIRECTION_OUT,
359                             CATEGORY_CH,
360                             "CHANNEL SELECTION (first reply to setup)");
361                 add_trace("channel", "request", "any");
362                 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
363                 /* if no channel was replied */
364                 if (channel <= 0)
365                 {
366                         add_trace("conclusion", NULL, "no channel, protocol error");
367                         end_trace();
368                         ret = -111; // protocol error
369                         goto channelerror;
370                 }
371
372                 /* we will see, if our received channel is available */
373                 ret = seize_bchannel(channel, 1); // exclusively
374                 add_trace("channel", "available", ret<0?"no":"yes");
375                 if (ret < 0)
376                 {
377                         add_trace("conclusion", NULL, "replied channel not available");
378                         end_trace();
379                         goto channelerror;
380                 }
381                 add_trace("conclusion", NULL, "replied channel accepted");
382                 add_trace("connect", "channel", "%d", p_m_b_channel);
383                 end_trace();
384
385                 /* activate channel given by remote */
386                 bchannel_activate(p_m_mISDNport, p_m_b_index);
387         } else
388         {
389                 /*** we sent 'no channel available' ***/
390
391                 /* if not the first reply, but a connect, we are forced */
392                 if (prim==(CC_CONNECT | INDICATION) && p_state!=PORT_STATE_OUT_SETUP)
393                 {
394                         start_trace(p_m_mISDNport->portnum,
395                                     p_m_mISDNport->ifport->interface,
396                                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
397                                     p_dialinginfo.number,
398                                     DIRECTION_OUT,
399                                     CATEGORY_CH,
400                                     "CHANNEL SELECTION (connect)");
401                         add_trace("channel", "request", "no-channel");
402                         add_trace("channel", "reply", (channel>=0)?"%d%s":"(none)", channel, exclusive?" (forced)":"");
403                         if (channel > 0)
404                         {
405                                 goto use_from_connect;
406                         }
407                         ret = seize_bchannel(CHANNEL_ANY, 0); // any channel
408                         add_trace("channel", "available", ret<0?"no":"yes");
409                         if (ret < 0)
410                         {
411                                 add_trace("conclusion", NULL, "no channel available during call-waiting");
412                                 end_trace();
413                                 goto channelerror;
414                         }
415                         add_trace("conclusion", NULL, "using channel %d", p_m_b_channel);
416                         add_trace("connect", "channel", "%d", p_m_b_channel);
417                         end_trace();
418                         p_m_b_exclusive = 1; // we are done
419
420                         /* activate channel given by remote */
421                         bchannel_activate(p_m_mISDNport, p_m_b_index);
422                         return(0);
423                 }
424                 
425                 /* if not first reply, we are done */
426                 if (p_state != PORT_STATE_OUT_SETUP)
427                         return(0);
428
429                 start_trace(p_m_mISDNport->portnum,
430                             p_m_mISDNport->ifport->interface,
431                             nationalize(p_callerinfo.id, p_callerinfo.ntype),
432                             p_dialinginfo.number,
433                             DIRECTION_OUT,
434                             CATEGORY_CH,
435                             "CHANNEL SELECTION (first reply to setup)");
436                 add_trace("channel", "request", "no-channel");
437                 add_trace("channel", "reply", (channel>=0)?"%d":"(none)", channel);
438                 /* if first reply has no channel, we are done */
439                 if (channel <= 0)
440                 {
441                         add_trace("conclusion", NULL, "no channel until connect");
442                         end_trace();
443                         return(0);
444                 }
445
446                 /* we will see, if our received channel is available */
447                 PDEBUG(DEBUG_BCHANNEL, "- our during call-waiting, we get channel %d as first reply.\n", channel);
448                 use_from_connect:
449                 ret = seize_bchannel(channel, exclusive);
450                 add_trace("channel", "available", ret<0?"no":"yes");
451                 if (ret < 0)
452                 {
453                         add_trace("conclusion", NULL, "replied channel not available");
454                         end_trace();
455                         goto channelerror;
456                 }
457                 add_trace("conclusion", NULL, "replied channel accepted");
458                 add_trace("connect", "channel", "%d", p_m_b_channel);
459                 end_trace();
460                 p_m_b_exclusive = 1; // we are done
461
462                 /* activate channel given by remote */
463                 bchannel_activate(p_m_mISDNport, p_m_b_index);
464         }
465         return(0);
466
467         channelerror:
468         dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
469         l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
470
471         release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
472         enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
473         end_trace();
474         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
475         new_state(PORT_STATE_RELEASE);
476         p_m_delete = 1;
477         return(-34); /* to epoint: no channel available */
478 }
479
480
481 /*
482  * handles all indications
483  */
484 /* CC_SETUP INDICATION */
485 void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
486 {
487         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
488         SETUP_t *setup = (SETUP_t *)((unsigned long)data + headerlen);
489         int type, plan, present, screen, reason;
490         int coding, capability, mode, rate, multi, user, presentation, interpretation, hlc, exthlc;
491         int exclusive, channel;
492         int ret;
493         msg_t *dmsg;
494         unsigned char keypad[32] = "";
495         unsigned char useruser[128];
496         int useruser_len = 0, useruser_protocol;
497         class Endpoint *epoint;
498         struct message *message;
499
500         /* callref from nt-lib */
501         if (p_m_d_ntmode)
502         {
503                 /* nt-library now gives us the id via CC_SETUP */
504                 if (dinfo&(~0xff) == 0xff00)
505                 {
506                         PERROR("fatal software error: l3-stack gives us a process id 0xff00-0xffff\n");
507                         exit(-1);
508                 }
509                 l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN);
510                 if (p_m_d_l3id)
511                         add_trace("callref", "old", "0x%x", p_m_d_l3id);
512                 add_trace("callref", "new", "0x%x", dinfo);
513                 end_trace();
514                 if (p_m_d_l3id&(~0xff) == 0xff00)
515                         p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
516                 p_m_d_l3id = dinfo;
517                 p_m_d_ces = setup->ces;
518         }
519
520         l3_trace_header(prim, DIRECTION_IN);
521         dec_ie_calling_pn(setup->CALLING_PN, (Q931_info_t *)((unsigned long)data+headerlen), &calling_type, &calling_plan, &calling_present, &calling_screen, (unsigned char *)p_callerinfo.id, sizeof(p_callerinfo.id));
522         dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &called_type, &called_plan, (unsigned char *)p_dialinginfo.number, sizeof(p_dialinginfo.number));
523         dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
524 #ifdef CENTREX
525         /* te-mode: CNIP (calling name identification presentation) */
526         if (!p_m_d_ntmode)
527                 dec_facility_centrex(setup->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)p_callerinfo.name, sizeof(p_callerinfo.name));
528 #endif
529         dec_ie_useruser(setup->USER_USER, (Q931_info_t *)((unsigned long)data+headerlen), &useruser_protocol, useruser, &useruser_len);
530         dec_ie_complete(setup->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete);
531         dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *)((unsigned long)data+headerlen), &redir_type, &redir_plan, &redir_present, &redir_screen, &redir_reason, (unsigned char *)p_redirinfo.id, sizeof(p_redirinfo.id));
532         dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
533         dec_ie_hlc(setup->HLC, (Q931_info_t *)((unsigned long)data+headerlen), &hlc_coding, &interpretation, &presentation, &hlc, &exthlc);
534         dec_ie_bearer(setup->BEARER, (Q931_info_t *)((unsigned long)data+headerlen), &bearer_coding, &capability, &mode, &rate, &multi, &user);
535         end_trace();
536
537         /* if blocked, release call */
538         if (p_m_mISDNport->ifport->block)
539         {
540                 RELEASE_COMPLETE_t *release_complete;
541
542                 printlog("---  port#%d is blocked.\n", mISDNport->ifport->portnum);
543                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
544                 l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
545                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
546                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 27); /* temporary unavailable */
547                 add_trace("reason", NULL, "port blocked");
548                 end_trace();
549                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
550                 new_state(PORT_STATE_RELEASE);
551                 p_m_delete = 1;
552                 return;
553         }
554
555         /* caller info */
556         switch (present)
557         {
558                 case 1:
559                 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
560                 break;
561                 case 2:
562                 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
563                 break;
564                 default:
565                 p_callerinfo.present = INFO_PRESENT_ALLOWED;
566                 break;
567         }
568         switch (screen)
569         {
570                 case 0:
571                 p_callerinfo.screen = INFO_SCREEN_USER;
572                 break;
573                 default:
574                 p_callerinfo.screen = INFO_SCREEN_NETWORK;
575                 break;
576         }
577         switch (type)
578         {
579                 case -1:
580                 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
581                 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
582                 p_callerinfo.screen = INFO_SCREEN_NETWORK;
583                 break;
584                 case 0x1:
585                 p_callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
586                 break;
587                 case 0x2:
588                 p_callerinfo.ntype = INFO_NTYPE_NATIONAL;
589                 break;
590                 case 0x4:
591                 p_callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
592                 break;
593                 default:
594                 p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
595                 break;
596         }
597         p_callerinfo.isdn_port = p_m_portnum;
598         SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
599
600         /* dialing information */
601         SCAT(p_dialinginfo.number, (char *)keypad);
602         switch (type)
603         {
604                 case 0x1:
605                 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
606                 break;
607                 case 0x2:
608                 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
609                 break;
610                 case 0x4:
611                 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
612                 break;
613                 default:
614                 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
615                 break;
616         }
617         switch (present)
618         {
619                 case 1:
620                 p_redirinfo.present = INFO_PRESENT_RESTRICTED;
621                 break;
622                 case 2:
623                 p_redirinfo.present = INFO_PRESENT_NOTAVAIL;
624                 break;
625                 default:
626                 p_redirinfo.present = INFO_PRESENT_ALLOWED;
627                 break;
628         }
629         switch (screen)
630         {
631                 case 0:
632                 p_redirinfo.screen = INFO_SCREEN_USER;
633                 break;
634                 default:
635                 p_redirinfo.screen = INFO_SCREEN_NETWORK;
636                 break;
637         }
638         switch (reason)
639         {
640                 case 1:
641                 p_redirinfo.reason = INFO_REDIR_BUSY;
642                 break;
643                 case 2:
644                 p_redirinfo.reason = INFO_REDIR_NORESPONSE;
645                 break;
646                 case 15:
647                 p_redirinfo.reason = INFO_REDIR_UNCONDITIONAL;
648                 break;
649                 case 10:
650                 p_redirinfo.reason = INFO_REDIR_CALLDEFLECT;
651                 break;
652                 case 9:
653                 p_redirinfo.reason = INFO_REDIR_OUTOFORDER;
654                 break;
655                 default:
656                 p_redirinfo.reason = INFO_REDIR_UNKNOWN;
657                 break;
658         }
659         switch (type)
660         {
661                 case -1:
662                 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
663                 p_redirinfo.present = INFO_PRESENT_NULL; /* not redirecting */
664                 p_redirinfo.reason = INFO_REDIR_UNKNOWN;
665                 break;
666                 case 0x1:
667                 p_redirinfo.ntype = INFO_NTYPE_INTERNATIONAL;
668                 break;
669                 case 0x2:
670                 p_redirinfo.ntype = INFO_NTYPE_NATIONAL;
671                 break;
672                 case 0x4:
673                 p_redirinfo.ntype = INFO_NTYPE_SUBSCRIBER;
674                 break;
675                 default:
676                 p_redirinfo.ntype = INFO_NTYPE_UNKNOWN;
677                 break;
678         }
679         p_redirinfo.isdn_port = p_m_portnum;
680
681         /* bearer capability */
682         switch (capability)
683         {
684                 case -1:
685                 p_capainfo.bearer_capa = INFO_BC_AUDIO;
686                 user = (options.law=='a')?3:2;
687                 break;
688                 default:
689                 p_capainfo.bearer_capa = capability;
690                 break;
691         }
692         switch (mode)
693         {
694                 case 2:
695                 p_capainfo.bearer_mode = INFO_BMODE_PACKET;
696                 break;
697                 default:
698                 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
699                 break;
700         }
701         switch (user)
702         {
703                 case -1:
704                 p_capainfo.bearer_info1 = INFO_INFO1_NONE;
705                 break;
706                 default:
707                 p_capainfo.bearer_info1 = user + 0x80;
708                 break;
709         }
710
711         /* hlc */
712         switch (hlc)
713         {
714                 case -1:
715                 p_capainfo.hlc = INFO_HLC_NONE;
716                 break;
717                 default:
718                 p_capainfo.hlc = hlc + 0x80;
719                 break;
720         }
721         switch (exthlc)
722         {
723                 case -1:
724                 p_capainfo.exthlc = INFO_HLC_NONE;
725                 break;
726                 default:
727                 p_capainfo.exthlc = exthlc + 0x80;
728                 break;
729         }
730
731         /* process channel */
732         start_trace(p_m_mISDNport->portnum,
733                     p_m_mISDNport->ifport->interface,
734                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
735                     p_dialinginfo.number,
736                     DIRECTION_IN,
737                     CATEGORY_CH,
738                     "CHANNEL SELECTION (setup)");
739         if (exclusive<0)
740                 exclusive = 0;
741         if (channel == CHANNEL_NO)
742                 add_trace("channel", "request", "no-channel");
743         else
744                 add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":"");
745         if (channel==CHANNEL_NO && p_type==PORT_TYPE_DSS1_TE_IN)
746         {
747                 add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode");
748                 end_trace();
749                 ret = -6; // channel unacceptable
750                 goto no_channel;
751         }
752         if (channel <= 0) /* not given, no channel, whatever.. */
753                 channel = CHANNEL_ANY; /* any channel */
754         if (p_m_mISDNport->b_reserved >= p_m_mISDNport->b_num) // of out chan..
755         {
756                 add_trace("channel", "reserved", "%d", p_m_mISDNport->b_reserved);
757                 add_trace("conclusion", NULL, "all channels are reserved");
758                 end_trace();
759                 ret = -34; // no channel
760                 goto no_channel;
761         }
762         if (channel == CHANNEL_ANY)
763                 goto get_from_list;
764         if (channel > 0)
765         {
766                 /* check for given channel in selection list */
767                 selchannel = ifport->channel_in;
768                 while(selchannel)
769                 {
770                         if (selchannel->channel == channel || selchannel->channel == CHANNEL_FREE)
771                                 break;
772                         selchannel = selchannel->next;
773                 }
774                 if (!selchannel)
775                         channel = 0;
776
777                 /* exclusive channel requests must be in the list */
778                 if (exclusive)
779                 {
780                         if (!channel)
781                         {
782                                 add_trace("conclusion", NULL, "exclusively requested channel not in list");
783                                 end_trace();
784                                 ret = 6; // unacceptable
785                                 goto no_channel;
786                         }
787                         i = selchannel->channel-1-(selchannel->channel>=17);
788                         if (mISDNport->b_port[i] == NULL)
789                                 goto use_channel;
790                         add_trace("conclusion", NULL, "exclusively requested channel is busy");
791                         end_trace();
792                         ret = 6; // unacceptable
793                         goto no_channel;
794                 }
795
796                 /* requested channels in list will be used */
797                 if (channel)
798                 {
799                         i = selchannel->channel-1-(selchannel->channel>=17);
800                         if (mISDNport->b_port[i] == NULL)
801                                 goto use_channel;
802                 }
803
804                 /* if channel is not available or not in list, it must be searched */
805                 get_from_list:
806                 /* check for first free channel in list */
807                 channel = 0;
808                 selchannel = ifport->channel_in;
809                 while(selchannel)
810                 {
811                         switch(selchannel->channel)
812                         {
813                                 case CHANNEL_FREE: /* free channel */
814                                 add_trace("hunting", "channel", "free");
815                                 if (mISDNport->b_inuse >= mISDNport->b_num)
816                                         break; /* all channel in use or reserverd */
817                                 /* find channel */
818                                 i = 0;
819                                 while(i < mISDNport->b_num)
820                                 {
821                                         if (mISDNport->b_port[i] == NULL)
822                                         {
823                                                 channel = i+1+(i>=15);
824                                                 break;
825                                         }
826                                         i++;
827                                 }
828                                 break;
829
830                                 default:
831                                 add_trace("hunting", "channel", "%d", selchannel->channel);
832                                 if (selchannel->channel<1 || selchannel->channel==16)
833                                         break; /* invalid channels */
834                                 i = selchannel->channel-1-(selchannel->channel>=17);
835                                 if (i >= mISDNport->b_num)
836                                         break; /* channel not in port */
837                                 if (mISDNport->b_port[i] == NULL)
838                                 {
839                                         channel = selchannel->channel;
840                                         break;
841                                 }
842                                 break;
843                         }
844                         if (channel)
845                                 break; /* found channel */
846                         selchannel = selchannel->next;
847                 }
848                 if (!channel)
849                 {
850                         add_trace("conclusion", NULL, "no channel available");
851                         end_trace();
852                         ret = 6; // unacceptable
853                         goto no_channel;
854                 }
855         }
856
857         /* open channel */
858         use_channel:
859         ret = seize_bchannel(channel, 1);
860         if (ret < 0)
861         {
862                 add_trace("conclusion", NULL, "channel not available");
863                 end_trace();
864                 no_channel:
865                 RELEASE_COMPLETE_t *release_complete;
866
867                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
868                 l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
869                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
870                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
871                 end_trace();
872                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
873                 new_state(PORT_STATE_RELEASE);
874                 p_m_delete = 1;
875                 return;
876         }
877         add_trace("conclusion", NULL, "channel available");
878         add_trace("connect", "channel", "%d", p_m_b_channel);
879         end_trace();
880         bchannel_activate(p_m_mISDNport, p_m_b_index);
881
882         /* create endpoint */
883         if (p_epointlist)
884         {
885                 PERROR("SOFTWARE ERROR: incoming call but already got an endpoint, exitting...\n");
886                 exit(-1);
887         }
888         if (!(epoint = new Endpoint(p_serial, 0)))
889         {
890                 RELEASE_COMPLETE_t *release_complete;
891
892                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
893                 l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
894                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
895                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 41); /* temporary failure */
896                 end_trace();
897                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
898                 new_state(PORT_STATE_RELEASE);
899                 p_m_delete = 1;
900                 return;
901         }
902         if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
903         {
904                 PERROR("no memory for application\n");
905                 exit(-1);
906         }
907         if (!(epointlist_new(epoint->ep_serial)))
908         {
909                 PERROR("no memory for epointlist\n");
910                 exit(-1);
911         }
912         /* send setup message to endpoit */
913         PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup: %s->%s\n", p_name, p_callerinfo.id, p_dialinginfo.number);
914         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
915         message->param.setup.isdn_port = p_m_portnum;
916         message->param.setup.port_type = p_type;
917         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
918         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
919         memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
920         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
921         memcpy(message->param.setup.useruser.data, &useruser, useruser_len);
922         message->param.setup.useruser.len = useruser_len;
923         message->param.setup.useruser.protocol = useruser_protocol;
924         message_put(message);
925
926         new_state(PORT_STATE_IN_SETUP);
927 }
928
929 /* CC_INFORMATION INDICATION */
930 void Pdss1::information_ind(unsigned long prim, unsigned long dinfo, void *data)
931 {
932         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
933         INFORMATION_t *information = (INFORMATION_t *)((unsigned long)data + headerlen);
934         int type, plan;
935         unsigned char keypad[32] = "";
936         struct message *message;
937
938         l3_trace_header(prim, DIRECTION_IN);
939         dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, (unsigned char *)p_dialinginfo.number, sizeof(p_dialinginfo.number));
940         dec_ie_keypad(information->KEYPAD, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)keypad, sizeof(keypad));
941         dec_ie_complete(information->COMPLETE, (Q931_info_t *)((unsigned long)data+headerlen), &p_dialinginfo.sending_complete);
942         end_trace();
943
944         SCAT(p_dialinginfo.number, (char *)keypad);
945         switch (type)
946         {
947                 case 0x1:
948                 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
949                 break;
950                 case 0x2:
951                 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
952                 break;
953                 case 0x4:
954                 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
955                 break;
956                 default:
957                 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
958                 break;
959         }
960         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
961         memcpy(&message->param.information, &p_dialinginfo, sizeof(struct dialing_info));
962         message_put(message);
963         /* reset overlap timeout */
964         new_state(p_state);
965 }
966
967 /* CC_SETUP_ACCNOWLEDGE INDICATION */
968 void Pdss1::setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void *data)
969 {
970         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
971         SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *)((unsigned long)data + headerlen);
972         int exclusive, channel;
973         int coding, location, progress;
974         int ret;
975         struct message *message;
976
977         l3_trace_header(prim, DIRECTION_IN);
978         dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
979         dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
980         end_trace();
981
982         /* process channel */
983         ret = received_first_reply_to_setup(prim, exclusive, channel);
984         if (ret < 0)
985         {
986                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
987                 message->param.disconnectinfo.cause = -ret;
988                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
989                 message_put(message);
990                 new_state(PORT_STATE_RELEASE);
991                 p_m_delete = 1;
992                 return;
993         }
994
995         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_OVERLAP);
996         message_put(message);
997
998         new_state(PORT_STATE_OUT_OVERLAP);
999 }
1000
1001 /* CC_PROCEEDING INDICATION */
1002 void Pdss1::proceeding_ind(unsigned long prim, unsigned long dinfo, void *data)
1003 {
1004         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1005         CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *)((unsigned long)data + headerlen);
1006         int exclusive, channel;
1007         int coding, location, progress;
1008         int ret;
1009         struct message *message;
1010         int notify = -1, type, plan, present;
1011         char redir[32];
1012
1013         l3_trace_header(prim, DIRECTION_IN);
1014         dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1015         dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
1016         dec_ie_notify(NULL/*proceeding->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), &notify);
1017         dec_ie_redir_dn(proceeding->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
1018         end_trace();
1019
1020         ret = received_first_reply_to_setup(prim, exclusive, channel);
1021         if (ret < 0)
1022         {
1023                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1024                 message->param.disconnectinfo.cause = -ret;
1025                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1026                 message_put(message);
1027                 new_state(PORT_STATE_RELEASE);
1028                 p_m_delete = 1;
1029                 return;
1030         }
1031         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1032         message_put(message);
1033
1034         new_state(PORT_STATE_OUT_PROCEEDING);
1035         
1036         if (notify >= 0)
1037                 notify |= 0x80;
1038         else
1039                 notify = 0;
1040         if (type >= 0 || notify)
1041         {
1042                 if (!notify && type >= 0)
1043                         notify = 251;
1044                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1045                 message->param.notifyinfo.notify = notify;
1046                 SCPY(message->param.notifyinfo.id, redir);
1047                 /* redirection number */
1048                 switch (present)
1049                 {
1050                         case 1:
1051                         message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1052                         break;
1053                         case 2:
1054                         message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1055                         break;
1056                         default:
1057                         message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1058                         break;
1059                 }
1060                 switch (type)
1061                 {
1062                         case -1:
1063                         message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1064                         message->param.notifyinfo.present = INFO_PRESENT_NULL;
1065                         break;
1066                         case 1:
1067                         message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1068                         break;
1069                         case 2:
1070                         message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1071                         break;
1072                         case 4:
1073                         message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1074                         break;
1075                         default:
1076                         message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1077                         break;
1078                 }
1079                 message->param.notifyinfo.isdn_port = p_m_portnum;
1080                 message_put(message);
1081         }
1082 }
1083
1084 /* CC_ALERTING INDICATION */
1085 void Pdss1::alerting_ind(unsigned long prim, unsigned long dinfo, void *data)
1086 {
1087         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1088         ALERTING_t *alerting = (ALERTING_t *)((unsigned long)data + headerlen);
1089         int exclusive, channel;
1090         int coding, location, progress;
1091         int ret;
1092         struct message *message;
1093         int notify = -1, type, plan, present;
1094         char redir[32];
1095
1096         l3_trace_header(prim, DIRECTION_IN);
1097         dec_ie_channel_id(alerting->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1098         dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &location, &progress);
1099         dec_ie_notify(NULL/*alerting->NOTIFY*/, (Q931_info_t *)((unsigned long)data+headerlen), &notify);
1100         dec_ie_redir_dn(alerting->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
1101         end_trace();
1102
1103         /* process channel */
1104         ret = received_first_reply_to_setup(prim, exclusive, channel);
1105         if (ret < 0)
1106         {
1107                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1108                 message->param.disconnectinfo.cause = -ret;
1109                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1110                 message_put(message);
1111                 new_state(PORT_STATE_RELEASE);
1112                 p_m_delete = 1;
1113                 return;
1114         }
1115         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
1116         message_put(message);
1117
1118         new_state(PORT_STATE_OUT_ALERTING);
1119
1120         if (notify >= 0)
1121                 notify |= 0x80;
1122         else
1123                 notify = 0;
1124         if (type >= 0 || notify)
1125         {
1126                 if (!notify && type >= 0)
1127                         notify = 251;
1128                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1129                 message->param.notifyinfo.notify = notify;
1130                 SCPY(message->param.notifyinfo.id, redir);
1131                 switch (present)
1132                 {
1133                         case 1:
1134                         message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1135                         break;
1136                         case 2:
1137                         message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1138                         break;
1139                         default:
1140                         message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1141                         break;
1142                 }
1143                 switch (type)
1144                 {
1145                         case -1:
1146                         message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1147                         message->param.notifyinfo.present = INFO_PRESENT_NULL;
1148                         break;
1149                         case 1:
1150                         message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1151                         break;
1152                         case 2:
1153                         message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1154                         break;
1155                         case 4:
1156                         message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1157                         break;
1158                         default:
1159                         message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1160                         break;
1161                 }
1162                 message->param.notifyinfo.isdn_port = p_m_portnum;
1163                 message_put(message);
1164         }
1165 }
1166
1167 /* CC_CONNECT INDICATION */
1168 void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data)
1169 {
1170         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1171         CONNECT_t *connect = (CONNECT_t *)((unsigned long)data + headerlen);
1172         int exclusive, channel;
1173         int type, plan, present, screen;
1174         int ret;
1175         msg_t *dmsg;
1176         struct message *message;
1177         int bchannel_before;
1178         CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
1179
1180         if (p_m_d_ntmode)
1181                 p_m_d_ces = connect->ces;
1182
1183         l3_trace_header(prim, DIRECTION_IN);
1184         dec_ie_channel_id(connect->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1185         dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, &screen, (unsigned char *)p_connectinfo.id, sizeof(p_connectinfo.id));
1186 #ifdef CENTREX
1187         /* te-mode: CONP (connected name identification presentation) */
1188         if (!p_m_d_ntmode)
1189                 dec_facility_centrex(connect->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), (unsigned char *)p_connectinfo.name, sizeof(p_connectinfo.name));
1190 #endif
1191         end_trace();
1192
1193         /* select channel */
1194         bchannel_before = p_m_b_channel;
1195         ret = received_first_reply_to_setup(prim, exclusive, channel);
1196         if (ret < 0)
1197         {
1198                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1199                 message->param.disconnectinfo.cause = -ret;
1200                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1201                 message_put(message);
1202                 new_state(PORT_STATE_RELEASE);
1203                 p_m_delete = 1;
1204                 return;
1205         }
1206
1207         /* connect information */
1208         switch (present)
1209         {
1210                 case 1:
1211                 p_connectinfo.present = INFO_PRESENT_RESTRICTED;
1212                 break;
1213                 case 2:
1214                 p_connectinfo.present = INFO_PRESENT_NOTAVAIL;
1215                 break;
1216                 default:
1217                 p_connectinfo.present = INFO_PRESENT_ALLOWED;
1218                 break;
1219         }
1220         switch (screen)
1221         {
1222                 case 0:
1223                 p_connectinfo.screen = INFO_SCREEN_USER;
1224                 break;
1225                 default:
1226                 p_connectinfo.screen = INFO_SCREEN_NETWORK;
1227                 break;
1228         }
1229         switch (type)
1230         {
1231                 case 0x0:
1232                 p_connectinfo.present = INFO_PRESENT_NULL; /* no COLP info */
1233                 p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1234                 break;
1235                 case 0x1:
1236                 p_connectinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1237                 break;
1238                 case 0x2:
1239                 p_connectinfo.ntype = INFO_NTYPE_NATIONAL;
1240                 break;
1241                 case 0x4:
1242                 p_connectinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1243                 break;
1244                 default:
1245                 p_connectinfo.ntype = INFO_NTYPE_UNKNOWN;
1246                 break;
1247         }
1248         p_connectinfo.isdn_port = p_m_portnum;
1249         SCPY(p_connectingo.interface, p_m_mISDNport->ifport->interface->name);
1250
1251         /* send connect acknowledge */
1252         dmsg = create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT, dinfo, sizeof(CONNECT_ACKNOWLEDGE_t), p_m_d_ntmode);
1253         l3_trace_header(CC_CONNECT | RESPONSE, DIRECTION_OUT);
1254         connect_acknowledge = (CONNECT_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1255         /* if we had no bchannel before, we send it now */
1256         if (!bchannel_before && p_m_b_channel)
1257                 enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
1258         end_trace();
1259         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1260
1261         PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect (to '%s' COLP: '%s')\n", p_name, p_dialinginfo.number, p_connectinfo.id);
1262         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1263         memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
1264         message_put(message);
1265
1266         new_state(PORT_STATE_CONNECT);
1267 }
1268
1269 /* CC_DISCONNECT INDICATION */
1270 void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data)
1271 {
1272         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1273         DISCONNECT_t *disconnect = (DISCONNECT_t *)((unsigned long)data + headerlen);
1274         int location, cause;
1275         int coding, proglocation, progress;
1276         struct message *message;
1277
1278         l3_trace_header(prim, DIRECTION_IN);
1279         dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)((unsigned long)data+headerlen), &coding, &proglocation, &progress);
1280         dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1281         end_trace();
1282
1283         if (cause < 0)
1284                 cause = 16;
1285
1286         /* release if we are remote sends us no tones */
1287         if (p_m_mISDNport->is_earlyb)
1288         {
1289                 RELEASE_t *release;
1290                 msg_t *dmsg;
1291
1292                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) send release because remote disconnects AND provides no patterns (earlyb).\n", p_name);
1293                 dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, dinfo, sizeof(RELEASE_t), p_m_d_ntmode);
1294                 release = (RELEASE_t *)(dmsg->data + headerlen);
1295                 l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT);
1296                 enc_ie_cause(&release->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); /* normal */
1297                 end_trace();
1298                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1299
1300                 /* sending release to endpoint */
1301                 while(p_epointlist)
1302                 {
1303                         message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1304                         message->param.disconnectinfo.cause = cause;
1305                         message->param.disconnectinfo.location = location;
1306                         message_put(message);
1307                         /* remove epoint */
1308                         free_epointlist(p_epointlist);
1309                 }
1310                 new_state(PORT_STATE_RELEASE);
1311                 p_m_delete = 1;
1312                 return;
1313         }
1314
1315         /* sending disconnect to active endpoint and release to inactive endpoints */
1316         if (ACTIVE_EPOINT(p_epointlist))
1317         {
1318                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1319                 message->param.disconnectinfo.location = location;
1320                 message->param.disconnectinfo.cause = cause;
1321                 message_put(message);
1322         }
1323         while(INACTIVE_EPOINT(p_epointlist))
1324         {
1325                 message = message_create(p_serial, INACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1326                 message->param.disconnectinfo.location = location;
1327                 message->param.disconnectinfo.cause = cause;
1328                 message_put(message);
1329                 /* remove epoint */
1330                 free_epointid(INACTIVE_EPOINT(p_epointlist));
1331         }
1332         new_state(PORT_STATE_IN_DISCONNECT);
1333 }
1334
1335 /* CC_DISCONNECT INDICATION */
1336 void Pdss1::disconnect_ind_i(unsigned long prim, unsigned long dinfo, void *data)
1337 {
1338         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1339         DISCONNECT_t *disconnect = (DISCONNECT_t *)((unsigned long)data + headerlen);
1340         int location, cause;
1341
1342         /* cause */
1343         l3_trace_header(prim, DIRECTION_IN);
1344         if (p_m_d_collect_cause > 0)
1345         {
1346                 add_trace("old-cause", "location", "%d", p_m_d_collect_location);
1347                 add_trace("old-cause", "value", "%d", p_m_d_collect_cause);
1348         }
1349         dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1350         end_trace();
1351
1352         /* collect cause */
1353         if (cause == CAUSE_REJECTED) /* call rejected */
1354         {
1355                 p_m_d_collect_cause = CAUSE_REJECTED;
1356                 p_m_d_collect_location = location;
1357         } else
1358         if (cause==CAUSE_NORMAL && p_m_d_collect_cause!=CAUSE_REJECTED) /* reject via hangup */
1359         {
1360                 p_m_d_collect_cause = CAUSE_NORMAL;
1361                 p_m_d_collect_location = location;
1362         } else
1363         if (cause==CAUSE_BUSY && p_m_d_collect_cause!=CAUSE_REJECTED && p_m_d_collect_cause!=CAUSE_NORMAL) /* busy */
1364         {
1365                 p_m_d_collect_cause = CAUSE_BUSY;
1366                 p_m_d_collect_location = location;
1367         } else
1368         if (cause==CAUSE_OUTOFORDER && p_m_d_collect_cause!=CAUSE_BUSY && p_m_d_collect_cause!=CAUSE_REJECTED && p_m_d_collect_cause!=CAUSE_NORMAL) /* no L1 */
1369         {
1370                 p_m_d_collect_cause = CAUSE_OUTOFORDER;
1371                 p_m_d_collect_location = location;
1372         } else
1373         if (cause!=0 && cause!=CAUSE_NOUSER && p_m_d_collect_cause!=CAUSE_OUTOFORDER && p_m_d_collect_cause!=CAUSE_BUSY && p_m_d_collect_cause!=CAUSE_REJECTED && p_m_d_collect_cause!=CAUSE_NORMAL) /* anything if cause exists and not 18 */
1374         {
1375                 p_m_d_collect_cause = cause;
1376                 p_m_d_collect_location = location;
1377         }
1378         add_trace("new-cause", "location", "%d", p_m_d_collect_location);
1379         add_trace("new-cause", "value", "%d", p_m_d_collect_cause);
1380
1381 }
1382
1383 /* CC_RELEASE INDICATION */
1384 void Pdss1::release_ind(unsigned long prim, unsigned long dinfo, void *data)
1385 {
1386         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1387         RELEASE_t *release = (RELEASE_t *)((unsigned long)data + headerlen);
1388         msg_t *dmsg;
1389         int location, cause;
1390         struct message *message;
1391
1392         l3_trace_header(prim, DIRECTION_IN);
1393         dec_ie_cause(release->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1394         end_trace();
1395
1396         if (cause < 0)
1397                 cause = 16;
1398
1399         /* sending release to endpoint */
1400         while(p_epointlist)
1401         {
1402                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1403                 message->param.disconnectinfo.cause = cause;
1404                 message->param.disconnectinfo.location = location;
1405                 message_put(message);
1406                 /* remove epoint */
1407                 free_epointlist(p_epointlist);
1408         }
1409
1410         /* only in NT mode we must send release_complete, if we got a release confirm */
1411         if (prim == (CC_RELEASE | CONFIRM))
1412         {
1413                 /* sending release complete */
1414                 RELEASE_COMPLETE_t *release_complete;
1415
1416                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, dinfo, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
1417                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
1418                 l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
1419                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16);
1420                 end_trace();
1421                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1422         }
1423
1424         new_state(PORT_STATE_RELEASE);
1425         p_m_delete = 1;
1426 }
1427
1428 /* CC_RELEASE_COMPLETE INDICATION */
1429 void Pdss1::release_complete_ind(unsigned long prim, unsigned long dinfo, void *data)
1430 {
1431         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1432         RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *)((unsigned long)data + headerlen);
1433         int location, cause;
1434         struct message *message;
1435
1436         l3_trace_header(prim, DIRECTION_IN);
1437         dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)((unsigned long)data+headerlen), &location, &cause);
1438         end_trace();
1439
1440         if (cause < 0)
1441                 cause = 16;
1442
1443         /* sending release to endpoint */
1444         while(p_epointlist)
1445         {
1446                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1447                 message->param.disconnectinfo.cause = cause;
1448                 message->param.disconnectinfo.location = location;
1449                 message_put(message);
1450                 /* remove epoint */
1451                 free_epointlist(p_epointlist);
1452         }
1453
1454         PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete (cause %d)\n", p_name, cause);
1455         new_state(PORT_STATE_RELEASE);
1456         p_m_delete = 1;
1457 }
1458
1459 /* T312 timeout  */
1460 void Pdss1::t312_timeout(unsigned long prim, unsigned long dinfo, void *data)
1461 {
1462         struct message *message;
1463
1464         // trace is done at message_isdn()
1465         
1466         /* sending release to endpoint */
1467         while(p_epointlist)
1468         {
1469                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1470                 message->param.disconnectinfo.cause = p_m_d_collect_cause;
1471                 message->param.disconnectinfo.location = p_m_d_collect_location;
1472                 message_put(message);
1473                 /* remove epoint */
1474                 free_epointlist(p_epointlist);
1475         }
1476
1477         PDEBUG(DEBUG_ISDN, "Pdss1(%s) t312_timeout (collected cause %d location %d)\n", p_name, p_m_d_collect_cause, p_m_d_collect_location);
1478         new_state(PORT_STATE_RELEASE);
1479         p_m_delete = 1;
1480 }
1481
1482 /* CC_NOTIFY INDICATION */
1483 void Pdss1::notify_ind(unsigned long prim, unsigned long dinfo, void *data)
1484 {
1485         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1486         NOTIFY_t *notifying = (NOTIFY_t *)((unsigned long)data + headerlen);
1487         struct message *message;
1488         int notify, type, plan, present;
1489
1490         l3_trace_header(prim, DIRECTION_IN);
1491         dec_ie_notify(notifying->NOTIFY, (Q931_info_t *)((unsigned long)data+headerlen), &notify);
1492         dec_ie_redir_dn(notifying->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)message->param.notifyinfo.id, sizeof(message->param.notifyinfo.id));
1493         end_trace();
1494
1495         if (!ACTIVE_EPOINT(p_epointlist))
1496         {
1497                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) there is no active endpoint to notify to.\n", p_name);
1498                 return;
1499         }
1500         /* notification indicator */
1501         if (notify < 0)
1502                 return;
1503         notify |= 0x80;
1504         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1505         message->param.notifyinfo.notify = notify;
1506         /* redirection number */
1507         switch (present)
1508         {
1509                 case 1:
1510                 message->param.notifyinfo.present = INFO_PRESENT_RESTRICTED;
1511                 break;
1512                 case 2:
1513                 message->param.notifyinfo.present = INFO_PRESENT_NOTAVAIL;
1514                 break;
1515                 default:
1516                 message->param.notifyinfo.present = INFO_PRESENT_ALLOWED;
1517                 break;
1518         }
1519         switch (type)
1520         {
1521                 case -1:
1522                 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1523                 message->param.notifyinfo.present = INFO_PRESENT_NULL;
1524                 break;
1525                 case 1:
1526                 message->param.notifyinfo.ntype = INFO_NTYPE_INTERNATIONAL;
1527                 break;
1528                 case 2:
1529                 message->param.notifyinfo.ntype = INFO_NTYPE_NATIONAL;
1530                 break;
1531                 case 4:
1532                 message->param.notifyinfo.ntype = INFO_NTYPE_SUBSCRIBER;
1533                 break;
1534                 default:
1535                 message->param.notifyinfo.ntype = INFO_NTYPE_UNKNOWN;
1536                 break;
1537         }
1538         message->param.notifyinfo.isdn_port = p_m_portnum;
1539         message_put(message);
1540 }
1541
1542
1543 /* CC_HOLD INDICATION */
1544 void Pdss1::hold_ind(unsigned long prim, unsigned long dinfo, void *data)
1545 {
1546         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1547 //      HOLD_t *hold = (HOLD_t *)((unsigned long)data + headerlen);
1548         struct message *message;
1549         HOLD_REJECT_t *hold_reject;
1550         HOLD_ACKNOWLEDGE_t *hold_acknowledge;
1551         msg_t *dmsg;
1552 //      class Endpoint *epoint;
1553
1554         l3_trace_header(prim, DIRECTION_IN);
1555         end_trace();
1556
1557         if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold)
1558         {
1559
1560                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) there is no endpoint to notify hold OR we are already on hold, so we reject.\n", p_name);
1561
1562                 dmsg = create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, dinfo, sizeof(HOLD_REJECT_t), p_m_d_ntmode);
1563                 hold_reject = (HOLD_REJECT_t *)(dmsg->data + headerlen);
1564                 l3_trace_header(CC_HOLD_REJECT | REQUEST, DIRECTION_OUT);
1565                 enc_ie_cause(&hold_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
1566                 end_trace();
1567                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1568
1569                 return;
1570         }
1571
1572         /* notify the hold of call */
1573         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1574         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1575         message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1576         message_put(message);
1577
1578         /* deactivate bchannel */
1579         start_trace(p_m_mISDNport->portnum,
1580                     p_m_mISDNport->ifport->interface,
1581                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
1582                     p_dialinginfo.number,
1583                     DIRECTION_OUT,
1584                     CATEGORY_CH,
1585                     "CHANNEL RELEASE (hold)");
1586         add_trace("disconnect", "channel", "%d", p_m_b_channel);
1587         end_trace();
1588         free_bchannel();
1589 prüfen, ob bei allen alloc_bchannel/free_bchannel ein trace erfolgt
1590
1591         /* set hold state */
1592         p_m_hold = 1;
1593 #if 0
1594         epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
1595         if (epoint && p_m_d_ntmode)
1596         {
1597                 p_m_timeout = p_settings.tout_hold;
1598                 time(&p_m_timer);
1599         }
1600 #endif
1601
1602         /* acknowledge hold */
1603         dmsg = create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE, dinfo, sizeof(HOLD_ACKNOWLEDGE_t), p_m_d_ntmode);
1604         hold_acknowledge = (HOLD_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1605         l3_trace_header(CC_HOLD_ACKNOWLEDGE | REQUEST, DIRECTION_OUT);
1606         end_trace();
1607         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1608 }
1609
1610
1611 /* CC_RETRIEVE INDICATION */
1612 void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data)
1613 {
1614         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1615         RETRIEVE_t *retrieve = (RETRIEVE_t *)((unsigned long)data + headerlen);
1616         RETRIEVE_REJECT_t *retrieve_reject;
1617         RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
1618         struct message *message;
1619         int channel, exclusive, cause;
1620         msg_t *dmsg;
1621         int ret;
1622
1623         l3_trace_header(prim, DIRECTION_IN);
1624         dec_ie_channel_id(retrieve->CHANNEL_ID, (Q931_info_t *)((unsigned long)data+headerlen), &exclusive, &channel);
1625         end_trace();
1626
1627         if (!p_m_hold)
1628         {
1629                 cause = 101; /* incompatible state */
1630                 reject:
1631                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) we are not on hold, so we reject (cazse %d).\n", p_name, cause);
1632
1633                 dmsg = create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, dinfo, sizeof(RETRIEVE_REJECT_t), p_m_d_ntmode);
1634                 retrieve_reject = (RETRIEVE_REJECT_t *)(dmsg->data + headerlen);
1635                 l3_trace_header(CC_RETRIEVE_REJECT | REQUEST, DIRECTION_OUT);
1636                 enc_ie_cause(&retrieve_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, cause);
1637                 end_trace();
1638                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1639
1640                 return;
1641         }
1642
1643         /* notify the retrieve of call */
1644         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1645         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1646         message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
1647         message_put(message);
1648
1649
1650
1651 mach den channel-kram, wie beim setup
1652
1653
1654
1655
1656
1657
1658
1659
1660         
1661         /* channel_id */
1662         start_trace(p_m_mISDNport->portnum,
1663                     p_m_mISDNport->ifport->interface,
1664                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
1665                     p_dialinginfo.number,
1666                     DIRECTION_IN,
1667                     CATEGORY_CH,
1668                     "CHANNEL SELECTION (retrieve)");
1669         if (exclusive<0)
1670                 exclusive = 0;
1671 alle channels richtig convertieren 
1672         if (channel < 0)
1673                 channel = -1; /* any channel */
1674         if (channel == ANY_CHANNEL)
1675                 channel = -1; /* any channel */
1676         if (channel == CHANNEL_NO)
1677                 add_trace("channel", "request", "no-channel");
1678         else
1679                 add_trace("channel", "request", (channel>0)?"%d%s":"any", channel, exclusive?" (forced)":"");
1680         /* debug */
1681         if (channel==CHANNEL_NO && (p_type==PORT_TYPE_DSS1_TE_IN||p_type==PORT_TYPE_DSS1_TE_OUT))
1682         {
1683                 add_trace("conclusion", NULL, "incoming call-waiting not supported for TE-mode");
1684                 end_trace();
1685                 cause = 6;
1686                 goto reject;
1687         }
1688         /* open channel */
1689         ret = alloc_bchannel(channel, exclusive);
1690         if (ret < 0)
1691         {
1692                 PDEBUG(DEBUG_BCHANNEL, "- channel is not available (cause=%d), so we send a retrieve_reject.\n", -ret);
1693                 cause = -ret;
1694                 goto reject;
1695         }
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711         
1712         /* set hold state */
1713         p_m_hold = 0;
1714         p_m_timeout = 0;
1715
1716         /* acknowledge retrieve */
1717         dmsg = create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE, dinfo, sizeof(RETRIEVE_ACKNOWLEDGE_t), p_m_d_ntmode);
1718         retrieve_acknowledge = (RETRIEVE_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1719         l3_trace_header(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, DIRECTION_OUT);
1720         enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
1721         end_trace();
1722         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1723 }
1724
1725 /* CC_SUSPEND INDICATION */
1726 void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data)
1727 {
1728         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1729         SUSPEND_t *suspend = (SUSPEND_t *)((unsigned long)data + headerlen);
1730         SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
1731         SUSPEND_REJECT_t *suspend_reject;
1732         struct message *message;
1733         class Endpoint *epoint;
1734         unsigned char callid[8];
1735         int len;
1736         msg_t *dmsg;
1737         int ret = -31; /* normal, unspecified */
1738
1739         l3_trace_header(prim, DIRECTION_IN);
1740         dec_ie_call_id(suspend->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1741         end_trace();
1742
1743         if (!ACTIVE_EPOINT(p_epointlist))
1744         {
1745                 reject:
1746                 dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, dinfo, sizeof(SUSPEND_REJECT_t), p_m_d_ntmode);
1747                 suspend_reject = (SUSPEND_REJECT_t *)(dmsg->data + headerlen);
1748                 l3_trace_header(CC_SUSPEND_REJECT | REQUEST, DIRECTION_OUT);
1749                 enc_ie_cause(&suspend_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1750                 end_trace();
1751                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1752
1753                 return;
1754         }
1755
1756         /* call id */
1757         if (len<0) len = 0;
1758
1759         /* check if call id is in use */
1760         epoint = epoint_first;
1761         while(epoint)
1762         {
1763                 if (epoint->ep_park)
1764                 {
1765                         if (epoint->ep_park_len == len)
1766                         if (!memcmp(epoint->ep_park_callid, callid, len))
1767                         {
1768                                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) call id is in use, so we reject.\n", p_name);
1769                                 ret = -84; /* call id in use */
1770                                 goto reject;
1771                         }
1772                 }
1773                 epoint = epoint->next;
1774         }
1775
1776         /* notify the hold of call */
1777         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1778         message->param.notifyinfo.notify = INFO_NOTIFY_USER_SUSPENDED;
1779         message->param.notifyinfo.local = 1; /* call is held by supplementary service */
1780         message_put(message);
1781
1782         /* deactivate bchannel */
1783         start_trace(p_m_mISDNport->portnum,
1784                     p_m_mISDNport->ifport->interface,
1785                     nationalize(p_callerinfo.id, p_callerinfo.ntype),
1786                     p_dialinginfo.number,
1787                     DIRECTION_OUT,
1788                     CATEGORY_CH,
1789                     "CHANNEL RELEASE (suspend)");
1790         add_trace("disconnect", "channel", "%d", p_m_b_channel);
1791         end_trace();
1792         free_bchannel();
1793
1794         /* sending suspend to endpoint */
1795         while (p_epointlist)
1796         {
1797                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_SUSPEND);
1798                 memcpy(message->param.parkinfo.callid, callid, sizeof(message->param.parkinfo.callid));
1799                 message->param.parkinfo.len = len;
1800                 message_put(message);
1801                 /* remove epoint */
1802                 free_epointlist(p_epointlist);
1803         }
1804
1805         /* sending SUSPEND_ACKNOWLEDGE */
1806         dmsg = create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE, dinfo, sizeof(SUSPEND_ACKNOWLEDGE_t), p_m_d_ntmode);
1807         suspend_acknowledge = (SUSPEND_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1808         l3_trace_header(CC_SUSPEND_ACKNOWLEDGE | REQUEST, DIRECTION_OUT);
1809         end_trace();
1810         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1811
1812         new_state(PORT_STATE_RELEASE);
1813         p_m_delete = 1;
1814 }
1815
1816 /* CC_RESUME INDICATION */
1817 void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data)
1818 {
1819         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1820         RESUME_t *resume = (RESUME_t *)((unsigned long)data + headerlen);
1821         RESUME_REJECT_t *resume_reject;
1822         RESUME_ACKNOWLEDGE_t *resume_acknowledge;
1823         unsigned char callid[8];
1824         int len;
1825         int channel, exclusive;
1826         msg_t *dmsg;
1827         class Endpoint *epoint;
1828         struct message *message;
1829         int ret;
1830
1831         /* callref from nt-lib */
1832         if (p_m_d_ntmode)
1833         {
1834                 /* nt-library now gives us the id via CC_RESUME */
1835                 if (dinfo&(~0xff) == 0xff00)
1836                 {
1837                         PERROR("fatal software error: l3-stack gives us a process id 0xff00-0xffff\n");
1838                         exit(-1);
1839                 }
1840                 l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN);
1841                 if (p_m_d_l3id)
1842                         add_trace("callref", "old", "0x%x", p_m_d_l3id);
1843                 add_trace("callref", "new", "0x%x", dinfo);
1844                 end_trace();
1845                 if (p_m_d_l3id&(~0xff) == 0xff00)
1846                         p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
1847                 p_m_d_l3id = dinfo;
1848                 p_m_d_ces = setup->ces;
1849         }
1850
1851         l3_trace_header(prim, DIRECTION_IN);
1852         dec_ie_call_id(resume->CALL_ID, (Q931_info_t *)((unsigned long)data+headerlen), callid, &len);
1853         end_trace();
1854
1855         /* if blocked, release call */
1856         if (p_m_mISDNport->ifport->block)
1857         {
1858                 RELEASE_COMPLETE_t *release_complete;
1859
1860                 printlog("---  port#%d is blocked.\n", mISDNport->ifport->portnum);
1861                 ret = -27;
1862                 goto reject;
1863         }
1864
1865         /* call id */
1866         if (len<0) len = 0;
1867
1868         /* channel_id */
1869         exclusive = 0;
1870         channel = -1; /* any channel */
1871
1872         /* hunt channel */
1873         ret = hunt_bchannel(channel, exclusive);
1874         if (ret < 0)
1875         {
1876                 reject:
1877                 dmsg = create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT, dinfo, sizeof(RESUME_REJECT_t), p_m_d_ntmode);
1878                 resume_reject = (RESUME_REJECT_t *)(dmsg->data + headerlen);
1879                 l3_trace_header(CC_RESUME_REJECT | REQUEST, DIRECTION_OUT);
1880                 enc_ie_cause(&resume_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, -ret);
1881                 if (ret == -27)
1882                         add_trace("reason", NULL, "port blocked");
1883                 end_trace();
1884                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1885                 new_state(PORT_STATE_RELEASE);
1886                 p_m_delete = 1;
1887                 return;
1888         }
1889
1890         /* create endpoint */
1891         if (p_epointlist)
1892         {
1893                 PERROR("SOFTWARE ERROR: incoming resume but already got an endpoint, exitting...\n");
1894                 exit(-1);
1895         }
1896         ret = -85; /* no call suspended */
1897         epoint = epoint_first;
1898         while(epoint)
1899         {
1900                 if (epoint->ep_park)
1901                 {
1902                         ret = -83; /* suspended call exists, but this not */
1903                         if (epoint->ep_park_len == len)
1904                         if (!memcmp(epoint->ep_park_callid, callid, len))
1905                                 break;
1906                 }
1907                 epoint = epoint->next;
1908         }
1909         if (!epoint)
1910         {
1911                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) no suspended call, so we reject with cause %d.\n", p_name, ret);
1912                 goto reject;
1913         }
1914
1915         if (!(epointlist_new(epoint->ep_serial)))
1916         {
1917                 PERROR("no memory for epointlist\n");
1918                 exit(-1);
1919         }
1920         if (!(epoint->portlist_new(p_serial, p_type, p_m_mISDNport->is_earlyb)))
1921         {
1922                 PERROR("no memory for portlist\n");
1923                 exit(-1);
1924         }
1925         PDEBUG(DEBUG_ISDN, "Pdss1(%s) resume\n", p_name);
1926         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RESUME);
1927         message_put(message);
1928
1929         /* notify the resume of call */
1930         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
1931         message->param.notifyinfo.notify = INFO_NOTIFY_USER_RESUMED;
1932         message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
1933         message_put(message);
1934
1935         /* sending RESUME_ACKNOWLEDGE */
1936         dmsg = create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE, dinfo, sizeof(RESUME_ACKNOWLEDGE_t), p_m_d_ntmode);
1937         resume_acknowledge = (RESUME_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
1938         l3_trace_header(CC_RESUME_ACKNOWLEDGE | REQUEST, DIRECTION_OUT);
1939         enc_ie_channel_id(&resume_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
1940         end_trace();
1941         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
1942
1943         new_state(PORT_STATE_CONNECT);
1944 }
1945
1946
1947 /* CC_FACILITY INDICATION */
1948 void Pdss1::facility_ind(unsigned long prim, unsigned long dinfo, void *data)
1949 {
1950         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1951         FACILITY_t *facility = (FACILITY_t *)((unsigned long)data + headerlen);
1952         unsigned char facil[256];
1953         int facil_len;
1954         struct message *message;
1955
1956         l3_trace_header(prim, DIRECTION_IN);
1957         dec_ie_facility(facility->FACILITY, (Q931_info_t *)((unsigned long)data+headerlen), facil, &facil_len);
1958         end_trace();
1959
1960         /* facility */
1961         if (facil_len<=0)
1962                 return;
1963
1964         PDEBUG(DEBUG_ISDN, "Pdss1(%s) facility\n", p_name);
1965         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
1966         message->param.facilityinfo.len = facil_len;
1967         memcpy(message->param.facilityinfo.data, facil, facil_len);
1968         message_put(message);
1969 }
1970
1971
1972 /*
1973  * handler for isdn connections
1974  * incoming information are parsed and sent via message to the endpoint
1975  */
1976 void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
1977 {
1978         int i;
1979         int new_l3id;
1980         int timer_hex=0;
1981
1982         switch (prim)
1983         {
1984                 case CC_TIMEOUT | INDICATION:
1985                 l3_trace_header(prim, DIRECTION_IN);
1986                 if (p_m_d_ntmode)
1987                 {
1988                         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1989                         timer_hex = *((int *)(((char *)data)+headerlen));
1990                 }
1991                 if (timer_hex)
1992                         add_trace("timer", NULL, "%x", timer_hex);
1993                 end_trace();
1994                 if (timer_hex==0x312 && p_m_d_ntmode)
1995                         t312_timeout(prim, dinfo, data);
1996                 break;
1997
1998                 case CC_SETUP | INDICATION:
1999                 PDEBUG((DEBUG_BCHANNEL|DEBUG_ISDN), "Pdss1(%s) setup\n", p_name);
2000                 if (p_state != PORT_STATE_IDLE)
2001                 {
2002                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup again, IGNORING.\n", p_name);
2003                         break;
2004                 }
2005                 setup_ind(prim, dinfo, data);
2006                 break;
2007
2008                 case CC_SETUP | CONFIRM:
2009                 if (p_m_d_ntmode)
2010                 {
2011                         l3_trace_header(CC_NEW_CR | INDICATION, DIRECTION_IN);
2012                         add_trace("callref", "old", "0x%x", p_m_d_l3id);
2013                         /* nt-library now gives us a new id via CC_SETUP_CONFIRM */
2014                         if ((p_m_d_l3id&0xff00) != 0xff00)
2015                                 PERROR("    strange setup-procid 0x%x\n", p_m_d_l3id);
2016                         p_m_d_l3id = *((int *)(((u_char *)data)+ mISDNUSER_HEAD_SIZE));
2017                         add_trace("callref", "new", "0x%x", p_m_d_l3id);
2018                         end_trace();
2019                 }
2020                 end_trace;
2021                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup confirm (l3id=0x%x)\n", p_name, p_m_d_l3id);
2022                 break;
2023
2024                 case CC_INFORMATION | INDICATION:
2025                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) information\n", p_name);
2026                 information_ind(prim, dinfo, data);
2027                 break;
2028
2029                 case CC_SETUP_ACKNOWLEDGE | INDICATION:
2030                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup acknowledge\n", p_name);
2031                 if (p_state != PORT_STATE_OUT_SETUP)
2032                 {
2033                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
2034                         break;
2035                 }
2036                 setup_acknowledge_ind(prim, dinfo, data);
2037                 break;
2038
2039                 case CC_PROCEEDING | INDICATION:
2040                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) proceeding\n", p_name);
2041                 if (p_state != PORT_STATE_OUT_SETUP
2042                  && p_state != PORT_STATE_OUT_OVERLAP)
2043                 {
2044                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
2045                         break;
2046                 }
2047                 proceeding_ind(prim, dinfo, data);
2048                 break;
2049
2050                 case CC_ALERTING | INDICATION:
2051                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) alerting\n", p_name);
2052                 if (p_state != PORT_STATE_OUT_SETUP
2053                  && p_state != PORT_STATE_OUT_OVERLAP
2054                  && p_state != PORT_STATE_OUT_PROCEEDING)
2055                 {
2056                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
2057                         break;
2058                 }
2059                 alerting_ind(prim, dinfo, data);
2060                 break;
2061
2062                 case CC_CONNECT | INDICATION:
2063                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect\n", p_name);
2064                 if (p_state != PORT_STATE_OUT_SETUP
2065                  && p_state != PORT_STATE_OUT_OVERLAP
2066                  && p_state != PORT_STATE_OUT_PROCEEDING
2067                  && p_state != PORT_STATE_OUT_ALERTING)
2068                 {
2069                         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);
2070                         break;
2071                 }
2072                 connect_ind(prim, dinfo, data);
2073                 if (p_m_d_notify_pending)
2074                 {
2075                         PDEBUG(DEBUG_ISDN, "received or connect, so we send pending notify message.\n");
2076                         message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2077                         message_free(p_m_d_notify_pending);
2078                         p_m_d_notify_pending = NULL;
2079                 }
2080                 break;
2081
2082                 case CC_CONNECT_ACKNOWLEDGE | INDICATION:
2083                 case CC_CONNECT | CONFIRM:
2084                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect_acknowlege.\n", p_name);
2085                 if (p_state == PORT_STATE_CONNECT_WAITING)
2086                         new_state(PORT_STATE_CONNECT);
2087                 if (p_m_d_notify_pending)
2088                 {
2089                         PDEBUG(DEBUG_ISDN, "received or connect-ack, so we send pending notify message.\n");
2090                         message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
2091                         message_free(p_m_d_notify_pending);
2092                         p_m_d_notify_pending = NULL;
2093                 }
2094                 break;
2095
2096                 case CC_DISCONNECT | INDICATION:
2097                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) disconnect\n", p_name);
2098                 disconnect_ind(prim, dinfo, data);
2099                 break;
2100
2101                 case CC_RELEASE | CONFIRM:
2102                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) release confirm\n", p_name);
2103                 case CC_RELEASE | INDICATION:
2104                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) release\n", p_name);
2105                 release_ind(prim, dinfo, data);
2106                 break;
2107
2108                 case CC_RELEASE_COMPLETE | INDICATION:
2109                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete.\n", p_name);
2110                 release_complete_ind(prim, dinfo, data);
2111                 break;
2112
2113                 case CC_RELEASE_COMPLETE | CONFIRM:
2114                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete (confirm).\n", p_name);
2115                 break;
2116
2117                 case CC_NOTIFY | INDICATION:
2118                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) notify\n", p_name);
2119                 notify_ind(prim, dinfo, data);
2120                 break;
2121
2122                 case CC_HOLD | INDICATION:
2123                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) hold\n", p_name);
2124                 hold_ind(prim, dinfo, data);
2125                 break;
2126
2127                 case CC_RETRIEVE | INDICATION:
2128                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) retrieve\n", p_name);
2129                 retrieve_ind(prim, dinfo, data);
2130                 break;
2131
2132                 case CC_SUSPEND | INDICATION:
2133                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) suspend\n", p_name);
2134                 suspend_ind(prim, dinfo, data);
2135                 break;
2136
2137                 case CC_RESUME | INDICATION:
2138                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) resume\n", p_name);
2139                 resume_ind(prim, dinfo, data);
2140                 break;
2141
2142                 case CC_FACILITY | INDICATION:
2143                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) facility\n", p_name);
2144                 facility_ind(prim, dinfo, data);
2145                 break;
2146
2147                 case CC_RELEASE_CR | INDICATION:
2148                 l3_trace_header(CC_RELEASE_CR | INDICATION, DIRECTION_IN);
2149                 add_trace("callref", NULL, "0x%x", p_m_d_l3id);
2150                 end_trace();
2151                 if (p_m_d_ntmode)
2152                 {
2153                         if ((p_m_d_l3id&0xff00) == 0xff00)
2154                                 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
2155                 }
2156                 p_m_d_l3id = 0;
2157                 p_m_delete = 1;
2158                 /* sending release to endpoint in case we still have an endpoint
2159                  * NOTE: this only happens if the stack releases due to layer1
2160                  * or layer2 breakdown. otherwhise a release is received first.
2161                  */
2162                 while(p_epointlist)
2163                 {
2164                         struct message *message;
2165                         message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
2166                         message->param.disconnectinfo.cause = (p_m_d_collect_cause!=CAUSE_NOUSER)?p_m_d_collect_cause:CAUSE_UNSPECIFIED;
2167                         message->param.disconnectinfo.location = (p_m_d_collect_cause!=CAUSE_NOUSER)?p_m_d_collect_location:LOCATION_PRIVATE_LOCAL;
2168                         message_put(message);
2169                         /* remove epoint */
2170                         free_epointlist(p_epointlist);
2171
2172                         new_state(PORT_STATE_RELEASE);
2173                 }
2174                 break;
2175
2176                 case CC_NEW_CR | INDICATION:
2177                 l3_trace_header(prim, DIRECTION_IN);
2178                 if (p_m_d_l3id)
2179                         add_trace("callref", "old", "0x%x", p_m_d_l3id);
2180                 if (p_m_d_ntmode)
2181                 {
2182                         new_l3id = *((int *)(((u_char *)data+mISDNUSER_HEAD_SIZE)));
2183                         if (((new_l3id&0xff00)!=0xff00) && ((p_m_d_l3id&0xff00)==0xff00))
2184                                 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
2185                 } else
2186                 {
2187                         new_l3id = dinfo;
2188                 }
2189                 p_m_d_l3id = new_l3id;
2190                 add_trace("callref", "new", "0x%x", p_m_d_l3id);
2191                 end_trace();
2192                 break;
2193
2194                 default:
2195                 l3_trace_header(prim, DIRECTION_IN);
2196                 add_trace("unhandled", "prim", "0x%x", prim);
2197                 end_trace();
2198         }
2199 }
2200
2201 void Pdss1::new_state(int state)
2202 {
2203         class Endpoint *epoint;
2204
2205         /* set timeout */
2206         epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
2207         if (epoint && p_m_d_ntmode)
2208         {
2209                 if (state == PORT_STATE_IN_OVERLAP)
2210                 {
2211                         p_m_timeout = p_settings.tout_dialing;
2212                         time(&p_m_timer);
2213                 }
2214                 if (state != p_state)
2215                 {
2216                         if (state == PORT_STATE_IN_SETUP
2217                          || state == PORT_STATE_IN_OVERLAP)
2218                         {
2219                                 p_m_timeout = p_settings.tout_setup;
2220                                 time(&p_m_timer);
2221                         }
2222                         if (state == PORT_STATE_IN_PROCEEDING
2223                          || state == PORT_STATE_OUT_PROCEEDING)
2224                         {
2225                                 p_m_timeout = p_settings.tout_proceeding;
2226                                 time(&p_m_timer);
2227                         }
2228                         if (state == PORT_STATE_IN_ALERTING
2229                          || state == PORT_STATE_OUT_ALERTING)
2230                         {
2231                                 p_m_timeout = p_settings.tout_alerting;
2232                                 time(&p_m_timer);
2233                         }
2234                         if (state == PORT_STATE_CONNECT
2235                          || state == PORT_STATE_CONNECT_WAITING)
2236                         {
2237                                 p_m_timeout = 0;
2238                         }
2239                         if (state == PORT_STATE_IN_DISCONNECT
2240                          || state == PORT_STATE_OUT_DISCONNECT)
2241                         {
2242                                 p_m_timeout = p_settings.tout_disconnect;
2243                                 time(&p_m_timer);
2244                         }
2245                 }
2246         }
2247         
2248         Port::new_state(state);
2249 }
2250
2251
2252 /*
2253  * handler
2254  */
2255 int Pdss1::handler(void)
2256 {
2257         int ret;
2258
2259         if ((ret = Port::handler()))
2260                 return(ret);
2261
2262         /* handle destruction */
2263         if (p_m_delete && p_m_d_l3id==0)
2264         {
2265                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) doing pending release.\n", p_name);
2266                 delete this;
2267                 return(-1);
2268         }
2269
2270         return(0);
2271 }
2272
2273
2274 /*
2275  * handles all messages from endpoint
2276  */
2277 /* MESSAGE_INFORMATION */
2278 void Pdss1::message_information(unsigned long epoint_id, int message_id, union parameter *param)
2279 {
2280         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2281         INFORMATION_t *information;
2282         msg_t *dmsg;
2283
2284         if (param->information.number[0]) /* only if we have something to dial */
2285         {
2286                 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2287                 l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT);
2288                 information = (INFORMATION_t *)(dmsg->data + headerlen);
2289                 enc_ie_called_pn(&information->CALLED_PN, dmsg, 0, 1, (unsigned char *)param->information.number);
2290                 end_trace();
2291                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2292         }
2293         new_state(p_state);
2294 }
2295
2296
2297 int newteid = 0;
2298
2299 /* MESSAGE_SETUP */
2300 void Pdss1::message_setup(unsigned long epoint_id, int message_id, union parameter *param)
2301 {
2302         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2303         INFORMATION_t *information;
2304         SETUP_t *setup;
2305         msg_t *dmsg;
2306         int plan, type, screen, present, reason;
2307         int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
2308         int channel, exclusive;
2309         int i;
2310         struct epoint_list *epointlist;
2311
2312         /* release if port is blocked */
2313         if (p_m_mISDNport->ifport->block)
2314         {
2315                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2316                 message->param.disconnectinfo.cause = 27; // temp. unavail.
2317                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2318                 message_put(message);
2319                 new_state(PORT_STATE_RELEASE);
2320                 p_m_delete = 1;
2321                 return;
2322         }
2323
2324         /* copy setup infos to port */
2325         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
2326         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
2327         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
2328         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
2329 //              SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
2330
2331         /* only display at connect state: this case happens if endpoint is in connected mode */
2332         if (p_state==PORT_STATE_CONNECT)
2333         {
2334                 if (p_type!=PORT_TYPE_DSS1_NT_OUT
2335                  && p_type!=PORT_TYPE_DSS1_NT_IN)
2336                         return;
2337                 if (p_callerinfo.display[0])
2338                 {
2339                         /* sending information */
2340                         dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2341                         information = (INFORMATION_t *)(dmsg->data + headerlen);
2342                         l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT);
2343                         if (p_m_d_ntmode)
2344                                 enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_callerinfo.display);
2345                         end_trace();
2346                         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2347                         return;
2348                 }
2349         }
2350
2351         /* attach only if not already */
2352         epointlist = p_epointlist;
2353         while(epointlist)
2354         {
2355                 if (epointlist->epoint_id == epoint_id)
2356                         break;
2357                 epointlist = epointlist->next;
2358         }
2359         if (!epointlist)
2360         {
2361                 if (!(epointlist_new(epoint_id)))
2362                 {
2363                         PERROR("no memory for epointlist\n");
2364                         exit(-1);
2365                 }
2366         }
2367
2368         /* get channel */
2369         exclusive = 0;
2370         if (p_m_b_channel)
2371         {
2372                 channel = p_m_b_channel;
2373                 exclusive = p_m_b_exclusive;
2374         } else
2375                 channel = CHANNEL_ANY;
2376         /* nt-port with no channel, not reserverd */
2377         if (!p_m_b_channel && !p_m_b_reserve && p_type==PORT_TYPE_DSS1_NT_OUT)
2378                 channel = CHANNEL_NO;
2379
2380         /* creating l3id */
2381         l3_trace_header(CC_NEW_CR | REQUEST, DIRECTION_OUT);
2382         if (p_m_d_ntmode)
2383         {
2384                 i = 0;
2385                 while(i < 0x100)
2386                 {
2387                         if (p_m_mISDNport->procids[i] == 0)
2388                                 break;
2389                         i++;
2390                 }
2391                 if (i == 0x100)
2392                 {
2393                         struct message *message;
2394
2395                         add_trace("callref", NULL, "no free id");
2396                         end_trace();
2397                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
2398                         message->param.disconnectinfo.cause = 47;
2399                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2400                         message_put(message);
2401                         new_state(PORT_STATE_RELEASE);
2402                         p_m_delete = 1;
2403                         return;
2404                 }
2405                 p_m_mISDNport->procids[i] = 1;
2406                 p_m_d_l3id = 0xff00 | i;
2407         } else
2408         {
2409                 iframe_t ncr;
2410                 /* if we are in te-mode, we need to create a process first */
2411                 if (newteid++ > 0x7fff)
2412                         newteid = 0x0001;
2413                 p_m_d_l3id = (entity<<16) | newteid;
2414                 /* preparing message */
2415                 ncr.prim = CC_NEW_CR | REQUEST; 
2416                 ncr.addr = p_m_mISDNport->upper_id | FLG_MSG_DOWN;
2417                 ncr.dinfo = p_m_d_l3id;
2418                 ncr.len = 0;
2419                 /* send message */
2420                 mISDN_write(mISDNdevice, &ncr, mISDN_HEADER_LEN+ncr.len, TIMEOUT_1SEC);
2421 //              if (!dmsg)
2422 //                      goto nomem;
2423         }
2424         add_trace("callref", "new", "0x%x", p_m_d_l3id);
2425         end_trace();
2426
2427         /* preparing setup message */
2428         dmsg = create_l3msg(CC_SETUP | REQUEST, MT_SETUP, p_m_d_l3id, sizeof(SETUP_t), p_m_d_ntmode);
2429         l3_trace_header(CC_SETUP | REQUEST, DIRECTION_OUT);
2430         setup = (SETUP_t *)(dmsg->data + headerlen);
2431         /* channel information */
2432         if (channel >= 0) /* it should */
2433         {
2434                 enc_ie_channel_id(&setup->CHANNEL_ID, dmsg, exclusive, channel);
2435         }
2436         /* caller information */
2437         plan = 1;
2438         switch (p_callerinfo.ntype)
2439         {
2440                 case INFO_NTYPE_INTERNATIONAL:
2441                 type = 0x1;
2442                 break;
2443                 case INFO_NTYPE_NATIONAL:
2444                 type = 0x2;
2445                 break;
2446                 case INFO_NTYPE_SUBSCRIBER:
2447                 type = 0x4;
2448                 break;
2449                 default: /* INFO_NTYPE_UNKNOWN */
2450                 type = 0x0;
2451                 break;
2452         }
2453         switch (p_callerinfo.screen)
2454         {
2455                 case INFO_SCREEN_USER:
2456                 screen = 0;
2457                 break;
2458                 default: /* INFO_SCREEN_NETWORK */
2459                 screen = 3;
2460                 break;
2461         }
2462         switch (p_callerinfo.present)
2463         {
2464                 case INFO_PRESENT_RESTRICTED:
2465                 present = 1;
2466                 break;
2467                 case INFO_PRESENT_NOTAVAIL:
2468                 present = 2;
2469                 break;
2470                 default: /* INFO_PRESENT_ALLOWED */
2471                 present = 0;
2472                 break;
2473         }
2474         if (type >= 0)
2475                 enc_ie_calling_pn(&setup->CALLING_PN, dmsg, type, plan, present, screen, (unsigned char *)p_callerinfo.id);
2476         /* dialing information */
2477         if (p_dialinginfo.number[0]) /* only if we have something to dial */
2478         {
2479                 enc_ie_called_pn(&setup->CALLED_PN, dmsg, 0, 1, (unsigned char *)p_dialinginfo.number);
2480         }
2481         /* sending complete */
2482         if (p_dialinginfo.sending_complete)
2483                 enc_ie_complete(&setup->COMPLETE, dmsg, 1);
2484         /* sending user-user */
2485         if (param->setup.useruser.len)
2486         {
2487                 enc_ie_useruser(&setup->USER_USER, dmsg, param->setup.useruser.protocol, param->setup.useruser.data, param->setup.useruser.len);
2488         }
2489         /* redirecting number */
2490         plan = 1;
2491         switch (p_redirinfo.ntype)
2492         {
2493                 case INFO_NTYPE_INTERNATIONAL:
2494                 type = 0x1;
2495                 break;
2496                 case INFO_NTYPE_NATIONAL:
2497                 type = 0x2;
2498                 break;
2499                 case INFO_NTYPE_SUBSCRIBER:
2500                 type = 0x4;
2501                 break;
2502                 default: /* INFO_NTYPE_UNKNOWN */
2503                 type = 0x0;
2504                 break;
2505         }
2506         switch (p_redirinfo.screen)
2507         {
2508                 case INFO_SCREEN_USER:
2509                 screen = 0;
2510                 break;
2511                 default: /* INFO_SCREE_NETWORK */
2512                 screen = 3;
2513                 break;
2514         }
2515         switch (p_redirinfo.reason)
2516         {
2517                 case INFO_REDIR_BUSY:
2518                 reason = 1;
2519                 break;
2520                 case INFO_REDIR_NORESPONSE:
2521                 reason = 2;
2522                 break;
2523                 case INFO_REDIR_UNCONDITIONAL:
2524                 reason = 15;
2525                 break;
2526                 case INFO_REDIR_CALLDEFLECT:
2527                 reason = 10;
2528                 break;
2529                 case INFO_REDIR_OUTOFORDER:
2530                 reason = 9;
2531                 break;
2532                 default: /* INFO_REDIR_UNKNOWN */
2533                 reason = 0;
2534                 break;
2535         }
2536         switch (p_redirinfo.present)
2537         {
2538                 case INFO_PRESENT_NULL: /* no redir at all */
2539                 present = -1;
2540                 screen = -1;
2541                 reason = -1;
2542                 plan = -1;
2543                 type = -1;
2544                 break;
2545                 case INFO_PRESENT_RESTRICTED:
2546                 present = 1;
2547                 break;
2548                 case INFO_PRESENT_NOTAVAIL:
2549                 present = 2;
2550                 break;
2551                 default: /* INFO_PRESENT_ALLOWED */
2552                 present = 0;
2553                 break;
2554         }
2555         /* sending redirecting number only in ntmode */
2556         if (type >= 0 && p_m_d_ntmode)
2557                 enc_ie_redir_nr(&setup->REDIR_NR, dmsg, type, plan, present, screen, reason, (unsigned char *)p_redirinfo.id);
2558         /* bearer capability */
2559 //printf("hlc=%d\n",p_capainfo.hlc);
2560         coding = 0;
2561         capability = p_capainfo.bearer_capa;
2562         mode = p_capainfo.bearer_mode;
2563         rate = (mode==INFO_BMODE_CIRCUIT)?0x10:0x00;
2564         switch (p_capainfo.bearer_info1)
2565         {
2566                 case INFO_INFO1_NONE:
2567                 user = -1;
2568                 break;
2569                 default:
2570                 user = p_capainfo.bearer_info1 & 0x7f;
2571                 break;
2572         }
2573         enc_ie_bearer(&setup->BEARER, dmsg, coding, capability, mode, rate, -1, user);
2574         /* hlc */
2575         if (p_capainfo.hlc)
2576         {
2577                 coding = 0;
2578                 interpretation = 4;
2579                 presentation = 1;
2580                 hlc = p_capainfo.hlc & 0x7f;
2581                 exthlc = -1;
2582                 if (p_capainfo.exthlc)
2583                         exthlc = p_capainfo.exthlc & 0x7f;
2584                 enc_ie_hlc(&setup->HLC, dmsg, coding, interpretation, presentation, hlc, exthlc);
2585         }
2586
2587         /* display */
2588         if (p_callerinfo.display[0] && p_m_d_ntmode)
2589                 enc_ie_display(&setup->DISPLAY, dmsg, (unsigned char *)p_callerinfo.display);
2590 #ifdef CENTREX
2591         /* nt-mode: CNIP (calling name identification presentation) */
2592         if (p_callerinfo.name[0] && p_m_d_ntmode)
2593                 enc_facility_centrex(&setup->FACILITY, dmsg, (unsigned char *)p_callerinfo.name, 1);
2594 #endif
2595         end_trace();
2596
2597         /* send setup message now */
2598         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2599
2600         new_state(PORT_STATE_OUT_SETUP);
2601 }
2602
2603 /* MESSAGE_FACILITY */
2604 void Pdss1::message_facility(unsigned long epoint_id, int message_id, union parameter *param)
2605 {
2606         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2607         FACILITY_t *facility;
2608         msg_t *dmsg;
2609
2610         /* facility will not be sent to external lines */
2611         if (!p_m_d_ntmode)
2612                 return;
2613
2614         PDEBUG(DEBUG_ISDN, "Pdss1(%s) sending facility message\n", p_name);
2615
2616         /* sending facility */
2617         dmsg = create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, p_m_d_l3id, sizeof(FACILITY_t), p_m_d_ntmode);
2618         facility = (FACILITY_t *)(dmsg->data + headerlen);
2619         l3_trace_header(CC_FACILITY | REQUEST, DIRECTION_OUT);
2620         enc_ie_facility(&facility->FACILITY, dmsg, (unsigned char *)param->facilityinfo.data, param->facilityinfo.len);
2621         end_trace();
2622         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2623 }
2624
2625 /* MESSAGE_NOTIFY */
2626 void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parameter *param)
2627 {
2628         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2629         INFORMATION_t *information;
2630         NOTIFY_t *notification;
2631         int notify;
2632         int plan, type = -1, present;
2633         msg_t *dmsg;
2634
2635         PDEBUG(DEBUG_ISDN, "Pdss1(%s) sending information message\n", p_name);
2636         if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
2637                 notify = param->notifyinfo.notify & 0x7f;
2638         else
2639                 notify = -1;
2640         if (p_state != PORT_STATE_CONNECT)
2641         {
2642                 /* notify only allowed in active state */
2643                 notify = -1;
2644         }
2645         if (notify >= 0)
2646         {
2647                 plan = 1;
2648                 switch (param->notifyinfo.ntype)
2649                 {
2650                         case INFO_NTYPE_INTERNATIONAL:
2651                         type = 1;
2652                         break;
2653                         case INFO_NTYPE_NATIONAL:
2654                         type = 2;
2655                         break;
2656                         case INFO_NTYPE_SUBSCRIBER:
2657                         type = 4;
2658                         break;
2659                         default: /* INFO_NTYPE_UNKNOWN */
2660                         type = 0;
2661                         break;
2662                 }
2663                 switch (param->notifyinfo.present)
2664                 {
2665                         case INFO_PRESENT_NULL: /* no redir at all */
2666                         present = -1;
2667                         plan = -1;
2668                         type = -1;
2669                         break;
2670                         case INFO_PRESENT_RESTRICTED:
2671                         present = 1;
2672                         break;
2673                         case INFO_PRESENT_NOTAVAIL:
2674                         present = 2;
2675                         break;
2676                         default: /* INFO_PRESENT_ALLOWED */
2677                         present = 0;
2678                         break;
2679                 }
2680         }
2681
2682         if (notify<0 && !param->notifyinfo.display[0])
2683         {
2684                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) nothing to notify, nothing to display\n", p_name);
2685                 return;
2686         }
2687
2688         if (notify >= 0)
2689         {
2690                 if (p_state!=PORT_STATE_CONNECT)
2691                 {
2692                         /* queue notification */
2693                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) queueing notification because isdn port is not active state.\n", p_name);
2694                         if (p_m_d_notify_pending)
2695                                 message_free(p_m_d_notify_pending);
2696                         p_m_d_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
2697                         memcpy(&p_m_d_notify_pending->param, param, sizeof(union parameter));
2698                 } else
2699                 {
2700                         /* sending notification */
2701                         dmsg = create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, p_m_d_l3id, sizeof(NOTIFY_t), p_m_d_ntmode);
2702                         notification = (NOTIFY_t *)(dmsg->data + headerlen);
2703                         l3_trace_header(CC_NOTIFY | REQUEST, DIRECTION_OUT);
2704                         enc_ie_notify(&notification->NOTIFY, dmsg, notify);
2705                         /* sending redirection number only in ntmode */
2706                         if (type >= 0 && p_m_d_ntmode)
2707                                 enc_ie_redir_dn(&notification->REDIR_DN, dmsg, type, plan, present, (unsigned char *)param->notifyinfo.id);
2708                         if (param->notifyinfo.display[0] && p_m_d_ntmode)
2709                                 enc_ie_display(&notification->DISPLAY, dmsg, (unsigned char *)param->notifyinfo.display);
2710                         end_trace();
2711                         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2712                 }
2713         } else if (p_m_d_ntmode)
2714         {
2715                 /* sending information */
2716                 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2717                 information = (INFORMATION_t *)(dmsg->data + headerlen);
2718                 l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT);
2719                 enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)param->notifyinfo.display);
2720                 end_trace();
2721                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2722         }
2723 }
2724
2725 /* MESSAGE_OVERLAP */
2726 void Pdss1::message_overlap(unsigned long epoint_id, int message_id, union parameter *param)
2727 {
2728         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2729         SETUP_ACKNOWLEDGE_t *setup_acknowledge;
2730         msg_t *dmsg;
2731
2732         /* sending setup_acknowledge */
2733         dmsg = create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE, p_m_d_l3id, sizeof(SETUP_ACKNOWLEDGE_t), p_m_d_ntmode);
2734         setup_acknowledge = (SETUP_ACKNOWLEDGE_t *)(dmsg->data + headerlen);
2735         l3_trace_header(CC_SETUP_ACKNOWLEDGE | REQUEST, DIRECTION_OUT);
2736         /* channel information */
2737         if (p_state == PORT_STATE_IN_SETUP)
2738                 enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2739         /* progress information */
2740         if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2741          || p_capainfo.bearer_capa==INFO_BC_AUDIO
2742          || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2743         if (p_m_mISDNport->is_tones)
2744                 enc_ie_progress(&setup_acknowledge->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2745         end_trace();
2746         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2747
2748         new_state(PORT_STATE_IN_OVERLAP);
2749 }
2750
2751 /* MESSAGE_PROCEEDING */
2752 void Pdss1::message_proceeding(unsigned long epoint_id, int message_id, union parameter *param)
2753 {
2754         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2755         CALL_PROCEEDING_t *proceeding;
2756         msg_t *dmsg;
2757
2758         /* sending proceeding */
2759         dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
2760         proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
2761         l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT);
2762         /* channel information */
2763         if (p_state == PORT_STATE_IN_SETUP)
2764                 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2765         /* progress information */
2766         if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2767          || p_capainfo.bearer_capa==INFO_BC_AUDIO
2768          || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2769         if (p_m_mISDNport->is_tones)
2770                 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2771         end_trace();
2772         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2773
2774         new_state(PORT_STATE_IN_PROCEEDING);
2775 }
2776
2777 /* MESSAGE_ALERTING */
2778 void Pdss1::message_alerting(unsigned long epoint_id, int message_id, union parameter *param)
2779 {
2780         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2781         ALERTING_t *alerting;
2782         msg_t *dmsg;
2783
2784         /* NT-MODE in setup state we must send PROCEEDING first */
2785         if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
2786         {
2787                 CALL_PROCEEDING_t *proceeding;
2788
2789                 /* sending proceeding */
2790                 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
2791                 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
2792                 l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT);
2793                 /* channel information */
2794                 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2795                 /* progress information */
2796                 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2797                  || p_capainfo.bearer_capa==INFO_BC_AUDIO
2798                  || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2799                 enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2800                 end_trace();
2801                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2802                 new_state(PORT_STATE_IN_PROCEEDING);
2803         }
2804
2805         /* sending alerting */
2806         dmsg = create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING, p_m_d_l3id, sizeof(ALERTING_t), p_m_d_ntmode);
2807         alerting = (ALERTING_t *)(dmsg->data + headerlen);
2808         l3_trace_header(CC_ALERTING | REQUEST, DIRECTION_OUT);
2809         /* channel information */
2810         if (p_state == PORT_STATE_IN_SETUP)
2811                 enc_ie_channel_id(&alerting->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2812         /* progress information */
2813         if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2814          || p_capainfo.bearer_capa==INFO_BC_AUDIO
2815          || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2816         if (p_m_mISDNport->is_tones)
2817                 enc_ie_progress(&alerting->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2818         end_trace();
2819         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2820
2821         new_state(PORT_STATE_IN_ALERTING);
2822 }
2823
2824 /* MESSAGE_CONNECT */
2825 void Pdss1::message_connect(unsigned long epoint_id, int message_id, union parameter *param)
2826 {
2827         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2828         INFORMATION_t *information;
2829         CONNECT_t *connect;
2830         int type, plan, present, screen;
2831         msg_t *dmsg;
2832         class Endpoint *epoint;
2833
2834         /* NT-MODE in setup state we must send PROCEEDING first */
2835         if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
2836         {
2837                 CALL_PROCEEDING_t *proceeding;
2838
2839                 /* sending proceeding */
2840                 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
2841                 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
2842                 l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT);
2843                 /* channel information */
2844                 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
2845 //              /* progress information */
2846 //              if (p_capainfo.bearer_capa==INFO_BC_SPEECH
2847 //               || p_capainfo.bearer_capa==INFO_BC_AUDIO
2848 //               || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
2849 //              enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
2850                 end_trace();
2851                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2852                 new_state(PORT_STATE_IN_PROCEEDING);
2853         }
2854
2855         /* copy connected information */
2856         memcpy(&p_connectinfo, &param->connectinfo, sizeof(p_connectinfo));
2857
2858         /* only display at connect state */
2859         if (p_state == PORT_STATE_CONNECT)
2860         if (p_connectinfo.display[0])
2861         {
2862                 /* sending information */
2863                 dmsg = create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, p_m_d_l3id, sizeof(INFORMATION_t), p_m_d_ntmode);
2864                 information = (INFORMATION_t *)(dmsg->data + headerlen);
2865                 l3_trace_header(CC_INFORMATION | REQUEST, DIRECTION_OUT);
2866                 if (p_m_d_ntmode)
2867                         enc_ie_display(&information->DISPLAY, dmsg, (unsigned char *)p_connectinfo.display);
2868                 end_trace();
2869                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2870                 return;
2871         }
2872
2873         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)
2874         {
2875                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect command only possible in setup, proceeding or alerting state.\n", p_name);
2876                 return;
2877         }
2878
2879         /* preparing connect message */
2880         dmsg = create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT, p_m_d_l3id, sizeof(CONNECT_t), p_m_d_ntmode);
2881         connect = (CONNECT_t *)(dmsg->data + headerlen);
2882         l3_trace_header(CC_CONNECT | REQUEST, DIRECTION_OUT);
2883         /* connect information */
2884         plan = 1;
2885         switch (p_connectinfo.ntype)
2886         {
2887                 case INFO_NTYPE_INTERNATIONAL:
2888                 type = 0x1;
2889                 break;
2890                 case INFO_NTYPE_NATIONAL:
2891                 type = 0x2;
2892                 break;
2893                 case INFO_NTYPE_SUBSCRIBER:
2894                 type = 0x4;
2895                 break;
2896                 default: /* INFO_NTYPE_UNKNOWN */
2897                 type = 0x0;
2898                 break;
2899         }
2900         switch (param->connectinfo.screen)
2901         {
2902                 case INFO_SCREEN_USER:
2903                 screen = 0;
2904                 break;
2905                 default: /* INFO_SCREE_NETWORK */
2906                 screen = 3;
2907                 break;
2908         }
2909         switch (p_connectinfo.present)
2910         {
2911                 case INFO_PRESENT_NULL: /* no colp at all */
2912                 present = -1;
2913                 screen = -1;
2914                 plan = -1;
2915                 type = -1;
2916                 break;
2917                 case INFO_PRESENT_RESTRICTED:
2918                 present = 1;
2919                 break;
2920                 case INFO_PRESENT_NOTAVAIL:
2921                 present = 2;
2922                 break;
2923                 default: /* INFO_PRESENT_ALLOWED */
2924                 present = 0;
2925                 break;
2926         }
2927         if (type >= 0)
2928                 enc_ie_connected_pn(&connect->CONNECT_PN, dmsg, type, plan, present, screen, (unsigned char *)p_connectinfo.id);
2929         /* display */
2930         if (p_connectinfo.display[0] && p_m_d_ntmode)
2931                 enc_ie_display(&connect->DISPLAY, dmsg, (unsigned char *)p_connectinfo.display);
2932 #ifdef CENTREX
2933         /* nt-mode: CONP (connected name identification presentation) */
2934         if (p_connectinfo.name[0] && p_m_d_ntmode)
2935                 enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
2936 #endif
2937         /* date & time */
2938         if (p_m_d_ntmode)
2939         {
2940                 epoint = find_epoint_id(epoint_id);
2941                 enc_ie_date(&connect->DATE, dmsg, now, p_settings.no_seconds);
2942         }
2943         end_trace();
2944         /* finally send message */
2945         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2946
2947         if (p_m_d_ntmode)
2948                 new_state(PORT_STATE_CONNECT);
2949         else
2950                 new_state(PORT_STATE_CONNECT_WAITING);
2951         set_tone("", NULL);
2952 }
2953
2954 /* MESSAGE_DISCONNECT */
2955 void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union parameter *param)
2956 {
2957         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
2958         DISCONNECT_t *disconnect;
2959         RELEASE_COMPLETE_t *release_complete;
2960         msg_t *dmsg;
2961         struct message *message;
2962         char *p = NULL;
2963
2964         /* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
2965         if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->is_tones)
2966          || p_state==PORT_STATE_OUT_SETUP)
2967         {
2968                 /* sending release to endpoint */
2969                 while(p_epointlist)
2970                 {
2971                         message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
2972                         message->param.disconnectinfo.cause = 16;
2973                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
2974                         message_put(message);
2975                         /* remove epoint */
2976                         free_epointlist(p_epointlist);
2977                 }
2978                 /* sending release */
2979                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
2980                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
2981                 l3_trace_header(CC_RELEASE_COMPLETE | REQUEST, DIRECTION_OUT);
2982                 /* send cause */
2983                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
2984                 end_trace();
2985                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
2986                 new_state(PORT_STATE_RELEASE);
2987                 p_m_delete = 1;
2988                 return;
2989         }
2990
2991         /* NT-MODE in setup state we must send PROCEEDING first */
2992         if (p_state==PORT_STATE_IN_SETUP)
2993         {
2994                 CALL_PROCEEDING_t *proceeding;
2995
2996                 /* sending proceeding */
2997                 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
2998                 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
2999                 l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT);
3000                 /* channel information */
3001                 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3002                 /* progress information */
3003                 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3004                  || p_capainfo.bearer_capa==INFO_BC_AUDIO
3005                  || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3006                         enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3007                 end_trace();
3008                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3009                 new_state(PORT_STATE_IN_PROCEEDING);
3010         }
3011
3012         /* sending disconnect */
3013         dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode);
3014         disconnect = (DISCONNECT_t *)(dmsg->data + headerlen);
3015         l3_trace_header(CC_DISCONNECT | REQUEST, DIRECTION_OUT);
3016         /* progress information */
3017         if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3018          || p_capainfo.bearer_capa==INFO_BC_AUDIO
3019          || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3020         if (p_m_mISDNport->is_tones)
3021                 enc_ie_progress(&disconnect->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3022         /* send cause */
3023         enc_ie_cause(&disconnect->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3024         /* send display */
3025         if (param->disconnectinfo.display[0])
3026                 p = param->disconnectinfo.display;
3027         if (p) if (*p && p_m_d_ntmode)
3028                 enc_ie_display(&disconnect->DISPLAY, dmsg, (unsigned char *)p);
3029         end_trace();
3030         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3031         new_state(PORT_STATE_OUT_DISCONNECT);
3032 }
3033
3034 /* MESSAGE_RELEASE */
3035 void Pdss1::message_release(unsigned long epoint_id, int message_id, union parameter *param)
3036 {
3037         int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
3038         RELEASE_t *release;
3039         RELEASE_COMPLETE_t *release_complete;
3040         DISCONNECT_t *disconnect;
3041         msg_t *dmsg;
3042         class Endpoint *epoint;
3043         char *p = NULL;
3044
3045         /* if we have incoming disconnected, we may release */
3046         if (p_state==PORT_STATE_IN_DISCONNECT
3047          || p_state==PORT_STATE_OUT_DISCONNECT)
3048         {
3049                 /* sending release */
3050                 dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, p_m_d_l3id, sizeof(RELEASE_t), p_m_d_ntmode);
3051                 release = (RELEASE_t *)(dmsg->data + headerlen);
3052                 l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT);
3053                 /* send cause */
3054                 enc_ie_cause(&release->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3055                 end_trace();
3056                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3057                 new_state(PORT_STATE_RELEASE);
3058                 /* remove epoint */
3059                 remove_endpoint:
3060                 free_epointid(epoint_id);
3061                 l3_trace_header(CC_RELEASE_CR | REQUEST, DIRECTION_OUT);
3062                 add_trace("callref", "new", "0x%x", p_m_d_l3id);
3063                 end_trace();
3064                 if (p_m_d_ntmode)
3065                 {
3066                         if ((p_m_d_l3id&0xff00) == 0xff00)
3067                                 p_m_mISDNport->procids[p_m_d_l3id&0xff] = 0;
3068                 }
3069                 p_m_d_l3id = 0;
3070                 p_m_delete = 1;
3071                 return;
3072         }
3073         /* if we are on outgoing/incoming call setup, we may release complete */
3074         if (p_state==PORT_STATE_OUT_SETUP
3075          || p_state==PORT_STATE_IN_SETUP
3076 // NOTE: a bug in mISDNuser (see disconnect_req_out !!!)
3077          || p_state==PORT_STATE_OUT_PROCEEDING)
3078         {
3079                 /* sending release */
3080                 dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
3081                 release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
3082                 l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT);
3083                 /* send cause */
3084                 enc_ie_cause(&release_complete->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3085                 end_trace();
3086                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3087                 new_state(PORT_STATE_RELEASE);
3088                 goto remove_endpoint;
3089         }
3090
3091         /* NT-MODE in setup state we must send PROCEEDING first */
3092         if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
3093         {
3094                 CALL_PROCEEDING_t *proceeding;
3095
3096                 /* sending proceeding */
3097                 dmsg = create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, p_m_d_l3id, sizeof(CALL_PROCEEDING_t), p_m_d_ntmode);
3098                 proceeding = (CALL_PROCEEDING_t *)(dmsg->data + headerlen);
3099                 l3_trace_header(CC_PROCEEDING | REQUEST, DIRECTION_OUT);
3100                 /* channel information */
3101                 enc_ie_channel_id(&proceeding->CHANNEL_ID, dmsg, 1, p_m_b_channel);
3102                 /* progress information */
3103                 if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3104                  || p_capainfo.bearer_capa==INFO_BC_AUDIO
3105                  || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3106                         enc_ie_progress(&proceeding->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3107                 end_trace();
3108                 msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3109         }
3110
3111         /* sending disconnect */
3112         dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode);
3113         disconnect = (DISCONNECT_t *)(dmsg->data + headerlen);
3114         l3_trace_header(CC_DISCONNECT | REQUEST, DIRECTION_OUT);
3115         /* progress information */
3116         if (p_capainfo.bearer_capa==INFO_BC_SPEECH
3117          || p_capainfo.bearer_capa==INFO_BC_AUDIO
3118          || p_capainfo.bearer_capa==INFO_BC_DATAUNRESTRICTED_TONES)
3119         if (p_m_mISDNport->is_tones)
3120                 enc_ie_progress(&disconnect->PROGRESS, dmsg, 0, p_m_d_ntmode?1:5, 8);
3121         /* send cause */
3122         enc_ie_cause(&disconnect->CAUSE, dmsg, (p_m_d_ntmode && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
3123         /* send display */
3124         epoint = find_epoint_id(epoint_id);
3125         if (param->disconnectinfo.display[0])
3126                 p = param->disconnectinfo.display;
3127         if (p) if (*p && p_m_d_ntmode)
3128                 enc_ie_display(&disconnect->DISPLAY, dmsg, (unsigned char *)p);
3129         end_trace();
3130         msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
3131         new_state(PORT_STATE_RELEASE);
3132         free_epointid(epoint_id);
3133 //      p_m_delete = 1;
3134 }
3135
3136
3137 /*
3138  * endpoint sends messages to the port
3139  */
3140 int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
3141 {
3142         struct message *message;
3143
3144         if (PmISDN::message_epoint(epoint_id, message_id, param))
3145                 return(1);
3146
3147         switch(message_id)
3148         {
3149                 case MESSAGE_INFORMATION: /* overlap dialing */
3150                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) received dialing info '%s'.\n", p_name, param->information.number);
3151                 if (p_type==PORT_TYPE_DSS1_NT_OUT
3152                  && p_state!=PORT_STATE_OUT_OVERLAP
3153                  && p_state!=PORT_STATE_CONNECT
3154                  && p_state!=PORT_STATE_OUT_DISCONNECT
3155                  && p_state!=PORT_STATE_IN_DISCONNECT)
3156                 {
3157                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) (internal outgoing) ignoring information, invalid state.\n", p_name);
3158                         break;
3159                 }
3160                 if (p_type==PORT_TYPE_DSS1_TE_OUT
3161                  && p_state!=PORT_STATE_OUT_OVERLAP
3162                  && p_state!=PORT_STATE_OUT_PROCEEDING
3163                  && p_state!=PORT_STATE_OUT_ALERTING
3164                  && p_state!=PORT_STATE_CONNECT
3165                  && p_state!=PORT_STATE_OUT_DISCONNECT
3166                  && p_state!=PORT_STATE_IN_DISCONNECT)
3167                 {
3168                         if (options.deb & DEBUG_ISDN)
3169                                 PERROR("Pdss1(%s) (external outgoing) ignoring information, invalid state.\n", p_name);
3170                         break;
3171                 }
3172                 if ((p_type==PORT_TYPE_DSS1_NT_IN || p_type==PORT_TYPE_DSS1_TE_IN)
3173                  && p_state!=PORT_STATE_IN_OVERLAP
3174                  && p_state!=PORT_STATE_IN_PROCEEDING
3175                  && p_state!=PORT_STATE_IN_ALERTING
3176                  && p_state!=PORT_STATE_CONNECT
3177                  && p_state!=PORT_STATE_CONNECT_WAITING
3178                  && p_state!=PORT_STATE_OUT_DISCONNECT
3179                  && p_state!=PORT_STATE_IN_DISCONNECT)
3180                 {
3181                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) (incoming) ignoring information, invalid state.\n", p_name);
3182                         break;
3183                 }
3184                 message_information(epoint_id, message_id, param);
3185                 break;
3186
3187                 case MESSAGE_SETUP: /* dial-out command received from epoint */
3188                 PDEBUG((DEBUG_ISDN | DEBUG_BCHANNEL), "Pdss1(%s) isdn port received setup from '%s' to '%s'\n", p_name, param->setup.callerinfo.id, param->setup.dialinginfo.number);
3189                 if (p_state!=PORT_STATE_IDLE
3190                  && p_state!=PORT_STATE_CONNECT)
3191                 {
3192                         PERROR("Pdss1(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
3193                         break;
3194                 }
3195                 if (p_epointlist && p_state==PORT_STATE_IDLE)
3196                 {
3197                         PERROR("Pdss1(%s): software error: epoint pointer is set in idle state, how bad!! exitting.\n", p_name);
3198                         exit(-1);
3199                 }
3200                 /* note: pri is a special case, because links must be up for pri */ 
3201                 if (p_m_mISDNport->l1link || p_m_mISDNport->pri || !p_m_mISDNport->ntmode || p_state!=PORT_STATE_IDLE)
3202                 {
3203                         /* LAYER 1 is up, or we may send */
3204                         message_setup(epoint_id, message_id, param);
3205                 } else {
3206                         iframe_t act;
3207                         /* LAYER 1 id down, so we queue */
3208                         p_m_d_queue = message_create(epoint_id, p_serial, EPOINT_TO_PORT, message_id);
3209                         memcpy(&p_m_d_queue->param, param, sizeof(union parameter));
3210                         /* attach us */
3211                         if (!(epointlist_new(epoint_id)))
3212                         {
3213                                 PERROR("no memory for epointlist\n");
3214                                 exit(-1);
3215                         }
3216                         /* activate link */
3217                         PDEBUG(DEBUG_ISDN, "the L1 is down, we try to establish the link NT portnum=%d (%s).\n", p_m_mISDNport->portnum, p_name);
3218                         act.prim = PH_ACTIVATE | REQUEST; 
3219                         act.addr = p_m_mISDNport->upper_id | FLG_MSG_DOWN;
3220                         act.dinfo = 0;
3221                         act.len = 0;
3222                         mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3223 //                      /* set timeout */
3224 //                      p_m_mISDNport->l1timeout = now+3;
3225                 }
3226                 break;
3227
3228                 case MESSAGE_NOTIFY: /* display and notifications */
3229                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received notification: display='%s' notify=%d phone=%s\n", p_name, p_callerinfo.id, param->notifyinfo.display, param->notifyinfo.notify, param->notifyinfo.id);
3230                 message_notify(epoint_id, message_id, param);
3231                 break;
3232
3233                 case MESSAGE_FACILITY: /* facility message */
3234                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received facility.\n", p_name, p_callerinfo.id);
3235                 message_facility(epoint_id, message_id, param);
3236                 break;
3237
3238                 case MESSAGE_OVERLAP: /* more information is needed */
3239                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received setup acknowledge\n", p_name, p_callerinfo.id);
3240                 if (p_state!=PORT_STATE_IN_SETUP)
3241                 {
3242                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring setup acknowledge because isdn port is not incoming setup state.\n", p_name);
3243                         break;
3244                 }
3245                 message_overlap(epoint_id, message_id, param);
3246                 break;
3247
3248                 case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
3249                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received proceeding\n", p_name, p_callerinfo.id);
3250                 if (p_state!=PORT_STATE_IN_SETUP
3251                  && p_state!=PORT_STATE_IN_OVERLAP)
3252                 {
3253                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: proceeding command not possible in current state.\n", p_name);
3254                         break;
3255                 }
3256                 message_proceeding(epoint_id, message_id, param);
3257                 break;
3258
3259                 case MESSAGE_ALERTING: /* call of endpoint is ringing */
3260                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received alerting\n", p_name, p_callerinfo.id);
3261                 if (p_state!=PORT_STATE_IN_SETUP
3262                  && p_state!=PORT_STATE_IN_OVERLAP
3263                  && p_state!=PORT_STATE_IN_PROCEEDING)
3264                 {
3265                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: alerting command not possible in current state.\n", p_name);
3266                         break;
3267                 }
3268                 message_alerting(epoint_id, message_id, param);
3269                 break;
3270
3271                 case MESSAGE_CONNECT: /* call of endpoint is connected */
3272                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received connect\n", p_name, p_callerinfo.id);
3273                 if (p_state!=PORT_STATE_IN_SETUP
3274                  && p_state!=PORT_STATE_IN_OVERLAP
3275                  && p_state!=PORT_STATE_IN_PROCEEDING
3276                  && p_state!=PORT_STATE_IN_ALERTING
3277                  && !(p_state==PORT_STATE_CONNECT && p_m_d_ntmode))
3278                 {
3279                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: connect command not possible in current state.\n", p_name);
3280                         break;
3281                 }
3282                 message_connect(epoint_id, message_id, param);
3283                 break;
3284
3285                 case MESSAGE_DISCONNECT: /* call has been disconnected */
3286                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received disconnect cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
3287                 if (p_state!=PORT_STATE_IN_SETUP
3288                  && p_state!=PORT_STATE_IN_OVERLAP
3289                  && p_state!=PORT_STATE_IN_PROCEEDING
3290                  && p_state!=PORT_STATE_IN_ALERTING
3291                  && p_state!=PORT_STATE_OUT_SETUP
3292                  && p_state!=PORT_STATE_OUT_OVERLAP
3293                  && p_state!=PORT_STATE_OUT_PROCEEDING
3294                  && p_state!=PORT_STATE_OUT_ALERTING
3295                  && p_state!=PORT_STATE_CONNECT
3296                  && p_state!=PORT_STATE_CONNECT_WAITING)
3297                 {
3298                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: disconnect command not possible in current state.\n", p_name);
3299                         break;
3300                 }
3301                 message_disconnect(epoint_id, message_id, param);
3302                 break;
3303
3304                 case MESSAGE_RELEASE: /* release isdn port */
3305                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received release cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
3306                 if (p_state==PORT_STATE_RELEASE)
3307                 {
3308                         PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: release command not possible in RELEASE state.\n", p_name);
3309                         break;
3310                 }
3311                 message_release(epoint_id, message_id, param);
3312                 break;
3313
3314                 default:
3315                 PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message);
3316         }
3317
3318         return(1);
3319 }
3320
3321
3322
3323 /*
3324  * data from isdn-stack (layer-3) to pbx (port class)
3325  */
3326 /* NOTE: nt mode use mISDNuser_head_t as header */
3327 int stack2manager_nt(void *dat, void *arg)
3328 {
3329         class Port *port;
3330         class Pdss1 *pdss1;
3331         manager_t *mgr = (manager_t *)dat;
3332         msg_t *msg = (msg_t *)arg;
3333         mISDNuser_head_t *hh;
3334         struct mISDNport *mISDNport;
3335         char name[32];
3336
3337         if (!msg || !mgr)
3338                 return(-EINVAL);
3339
3340         /* note: nst is the first data feld of mISDNport */
3341         mISDNport = (struct mISDNport *)mgr->nst;
3342
3343         hh = (mISDNuser_head_t *)msg->data;
3344         PDEBUG(DEBUG_ISDN, "prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, msg->len);
3345
3346         /* find Port object of type ISDN */
3347         port = port_first;
3348         while(port)
3349         {
3350                 if (port->p_type == PORT_TYPE_DSS1_NT_IN || port->p_type == PORT_TYPE_DSS1_NT_OUT)
3351                 {
3352                         pdss1 = (class Pdss1 *)port;
3353 //PDEBUG(DEBUG_ISDN, "comparing dinfo = 0x%x with l3id 0x%x\n", hh->dinfo, pdss1->p_m_d_l3id);
3354                         /* check out correct stack */
3355                         if (pdss1->p_m_mISDNport == mISDNport)
3356                         /* check out correct id */
3357                         if ((hh->dinfo&0xffff0000) == (pdss1->p_m_d_l3id&0xffff0000))
3358                         {
3359                                 /* found port, the message belongs to */
3360                                 break;
3361                         }
3362                 }
3363                 port = port->next;
3364         }
3365         if (port)
3366         {
3367                 /* if process id is master process, but a child disconnects */
3368                 if ((hh->dinfo&0x0000ff00)!=0x0000ff00 && (pdss1->p_m_d_l3id&0x0000ff00)==0x0000ff00 && hh->prim==(CC_DISCONNECT|INDICATION))
3369                 {
3370                         /* send special indication for child disconnect */
3371                         pdss1->disconnect_ind_i(hh->prim, hh->dinfo, msg->data);
3372                         free_msg(msg);
3373                         return(0);
3374                 }
3375                 /* if process id and layer 3 id matches */
3376                 if (hh->dinfo == pdss1->p_m_d_l3id)
3377                 {
3378                         pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
3379                         free_msg(msg);
3380                         return(0);
3381                 }
3382         }
3383
3384         /* d-message */
3385         switch(hh->prim)
3386         {
3387                 case MGR_SHORTSTATUS | INDICATION:
3388                 case MGR_SHORTSTATUS | CONFIRM:
3389                 switch(hh->dinfo) {
3390                         case SSTATUS_L2_ESTABLISHED:
3391                         goto ss_estab;
3392                         case SSTATUS_L2_RELEASED:
3393                         goto ss_rel;
3394                 }
3395                 break;
3396
3397                 case DL_ESTABLISH | INDICATION:
3398                 case DL_ESTABLISH | CONFIRM:
3399                 ss_estab:
3400                 PDEBUG(DEBUG_ISDN, "establish data link (DL) NT portnum=%d TEI=%d\n", mISDNport->portnum, hh->dinfo);
3401                 if (mISDNport->ptp && hh->dinfo == 0)
3402                 {
3403                         if (mISDNport->l2establish)
3404                         {
3405                                 mISDNport->l2establish = 0;
3406                                 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
3407                         }
3408                         mISDNport->l2link = 1;
3409                         if (mISDNport->pri);
3410                                 mISDNport->l1link = 1; /* this is a hack, we also assume L1 to be active */
3411                 }
3412                 break;
3413
3414                 case DL_RELEASE | INDICATION:
3415                 case DL_RELEASE | CONFIRM:
3416                 ss_rel:
3417                 PDEBUG(DEBUG_ISDN, "release data link (DL) NT portnum=%d TEI=%d\n", mISDNport->portnum, hh->dinfo);
3418                 if (mISDNport->ptp && hh->dinfo == 0)
3419                 {
3420                         mISDNport->l2link = 0;
3421                         time(&mISDNport->l2establish);
3422                         PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
3423                 }
3424                 break;
3425
3426                 case CC_SETUP | INDICATION:
3427                 /* creating port object */
3428                 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3429                 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0)))
3430                 {
3431                         RELEASE_COMPLETE_t *release_complete;
3432                         msg_t *dmsg;
3433
3434                         PERROR("FATAL ERROR: cannot create port object.\n");
3435                         dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, hh->dinfo, sizeof(RELEASE_COMPLETE_t), mISDNport->ntmode);
3436                         release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + mISDN_HEADER_LEN);
3437                         enc_ie_cause_standalone(mISDNport->ntmode?&release_complete->CAUSE:NULL, dmsg, (mISDNport->ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47);
3438                         msg_queue_tail(&mISDNport->downqueue, dmsg);
3439                         break;
3440                 }
3441                 pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
3442                 break;
3443
3444                 case CC_RESUME | INDICATION:
3445                 /* creating port object */
3446                 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3447                 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL)))
3448                 {
3449                         SUSPEND_REJECT_t *suspend_reject;
3450                         msg_t *dmsg;
3451
3452                         PERROR("FATAL ERROR: cannot create port object.\n");
3453                         dmsg = create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, hh->dinfo, sizeof(SUSPEND_REJECT_t), mISDNport->ntmode);
3454                         suspend_reject = (SUSPEND_REJECT_t *)(dmsg->data + mISDN_HEADER_LEN);
3455                         enc_ie_cause_standalone(mISDNport->ntmode?&suspend_reject->CAUSE:NULL, dmsg, (mISDNport->ntmode)?1:0, 47);
3456                         msg_queue_tail(&mISDNport->downqueue, dmsg);
3457                         break;
3458                 }
3459                 pdss1->message_isdn(hh->prim, hh->dinfo, msg->data);
3460                 break;
3461
3462                 case CC_RELEASE_CR | INDICATION:
3463                 PDEBUG(DEBUG_ISDN, "%s: unhandled message from stack: call ref released (l3id=0x%x)\n", __FUNCTION__, hh->dinfo);
3464                 break;
3465
3466                 case CC_DISCONNECT | INDICATION:
3467
3468                 // fall throug
3469                 default:
3470                 PDEBUG(DEBUG_ISDN, "%s: unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", __FUNCTION__, hh->prim, hh->dinfo, msg->len);
3471                 return(-EINVAL);
3472         }
3473         free_msg(msg);
3474         return(0);
3475 }
3476
3477 /* NOTE: te mode use iframe_t as header */
3478 int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg)
3479 {
3480         class Port *port;
3481         class Pdss1 *pdss1;
3482         iframe_t *frm;
3483         char name[32];
3484
3485         if (!msg || !mISDNport)
3486                 return(-EINVAL);
3487         frm = (iframe_t *)msg->data;
3488         PDEBUG(DEBUG_ISDN, "prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
3489
3490         /* find Port object of type ISDN */
3491         port = port_first;
3492         while(port)
3493         {
3494                 if (port->p_type == PORT_TYPE_DSS1_TE_IN || port->p_type == PORT_TYPE_DSS1_TE_OUT)
3495                 {
3496                         pdss1 = (class Pdss1 *)port;
3497 //PDEBUG(DEBUG_ISDN, "comparing dinfo = 0x%x with l3id 0x%x\n", frm->dinfo, pdss1->p_m_d_l3id);
3498                         /* check out correct stack */
3499                         if (pdss1->p_m_mISDNport == mISDNport)
3500                         /* check out correct id */
3501                         if (frm->dinfo == pdss1->p_m_d_l3id)
3502                         {
3503                                 /* found port, the message belongs to */
3504                                 break;
3505                         }
3506                 }
3507                 port = port->next;
3508         }
3509         if (port)
3510         {
3511                 pdss1->message_isdn(frm->prim, frm->dinfo, msg->data);
3512                 free_msg(msg);
3513                 return(0);
3514         }
3515
3516         /* process new cr (before setup indication) */
3517 //printf("prim = 0x%x, looking for 0x%x\n",frm->prim, (CC_NEW_CR | INDICATION));
3518         if (frm->prim == (CC_NEW_CR | INDICATION))
3519         {
3520
3521                 /* creating port object */
3522                 SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
3523                 if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_TE_IN, mISDNport, name, NULL)))
3524                 {
3525                         RELEASE_COMPLETE_t *release_complete;
3526                         msg_t *dmsg;
3527
3528                         PERROR("FATAL ERROR: cannot create port object.\n");
3529                         dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, frm->dinfo, sizeof(RELEASE_COMPLETE_t), mISDNport->ntmode);
3530                         release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + mISDN_HEADER_LEN);
3531                         enc_ie_cause_standalone(mISDNport->ntmode?&release_complete->CAUSE:NULL, dmsg, (mISDNport->ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 47);
3532                         msg_queue_tail(&mISDNport->downqueue, dmsg);
3533                         free_msg(msg);
3534                         return(0);
3535                 }
3536                 /* l3id will be set from dinfo at message_isdn */
3537                 pdss1->message_isdn(frm->prim, frm->dinfo, msg->data);
3538                 free_msg(msg);
3539                 return(0);
3540         }
3541
3542         if (frm->prim == (CC_RELEASE_CR | INDICATION))
3543         {
3544                 PDEBUG(DEBUG_ISDN, "unhandled message from stack: call ref released (l3id=0x%x)\n", frm->dinfo);
3545                 free_msg(msg);
3546                 return(0);
3547         }
3548         PDEBUG(DEBUG_ISDN, "unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
3549         return(-EINVAL);
3550 }
3551
3552
3553 /*
3554  * sending message that were queued during L1 activation
3555  * or releasing port if link is down
3556  */
3557 void setup_queue(struct mISDNport *mISDNport, int link)
3558 {
3559         class Port *port;
3560         class Pdss1 *pdss1;
3561         struct message *message;
3562
3563         if (!mISDNport->ntmode)
3564                 return;
3565
3566         /* check all port objects for pending message */
3567         port = port_first;
3568         while(port)
3569         {
3570                 if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
3571                 {
3572                         pdss1 = (class Pdss1 *)port;
3573                         if (pdss1->p_m_mISDNport == mISDNport)
3574                         {
3575                                 if (pdss1->p_m_d_queue)
3576                                 {
3577                                         if (link)
3578                                         {
3579                                                 PDEBUG(DEBUG_ISDN, "the L1 became active, so we send queued message for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
3580                                                 /* LAYER 1 is up, so we send */
3581                                                 pdss1->message_setup(pdss1->p_m_d_queue->id_from, pdss1->p_m_d_queue->type, &pdss1->p_m_d_queue->param);
3582                                                 message_free(pdss1->p_m_d_queue);
3583                                                 pdss1->p_m_d_queue = NULL;
3584                                         } else
3585                                         {
3586                                                 PDEBUG(DEBUG_ISDN, "the L1 became NOT active, so we release port for portnum=%d (%s).\n", mISDNport->portnum, pdss1->p_name);
3587                                                 message = message_create(pdss1->p_serial, pdss1->p_m_d_queue->id_from, PORT_TO_EPOINT, MESSAGE_RELEASE);
3588                                                 message->param.disconnectinfo.cause = 27;
3589                                                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
3590                                                 message_put(message);
3591                                                 pdss1->new_state(PORT_STATE_RELEASE);
3592                                                 pdss1->p_m_delete = 1;
3593                                         }
3594                                 }
3595                         }
3596                 }
3597                 port = port->next;
3598         }
3599 }
3600
3601
3602
3603
3604