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