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