Added new option to interface.conf: "nonotify" to disable notify messages.
[lcr.git] / endpoint.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** The Endpoint is the link between the join and the port.                   **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13
14 unsigned int epoint_serial = 1; /* initial value must be 1, because 0== no epoint */
15
16 class Endpoint *epoint_first = NULL;
17
18
19 /*
20  * find the epoint with epoint_id
21  */ 
22 class Endpoint *find_epoint_id(unsigned int epoint_id)
23 {
24         class Endpoint *epoint = epoint_first;
25
26         while(epoint) {
27 //printf("comparing: '%s' with '%s'\n", name, epoint->name);
28                 if (epoint->ep_serial == epoint_id)
29                         return(epoint);
30                 epoint = epoint->next;
31         }
32
33         return(NULL);
34 }
35
36
37 /*
38  * endpoint constructor (link with either port or join id)
39  */
40 Endpoint::Endpoint(unsigned int port_id, unsigned int join_id)
41 {
42         class Port *port;
43         class Endpoint **epointpointer;
44         int earlyb = 0;
45
46         /* epoint structure */
47         PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Allocating enpoint %d and connecting it with:%s%s\n", epoint_serial, epoint_serial, (port_id)?" ioport":"", (join_id)?" join":"");
48
49         ep_portlist = NULL;
50         ep_app = NULL;
51         ep_use = 1;
52
53         /* add endpoint to chain */
54         next = NULL;
55         epointpointer = &epoint_first;
56         while(*epointpointer)
57                 epointpointer = &((*epointpointer)->next);
58         *epointpointer = this;
59
60         /* serial */
61         ep_serial = epoint_serial++;
62
63         /* link to join or port */
64         if (port_id) {
65                 port = find_port_id(port_id);
66                 if (port) {
67                         if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
68                                 earlyb = ((class PmISDN *)port)->p_m_mISDNport->earlyb;
69                         if (!portlist_new(port_id, port->p_type, earlyb))
70                                 FATAL("No memory for portlist.\n");
71                 }
72         }
73         ep_join_id = join_id;
74
75         ep_park = 0;
76         ep_park_len = 0;
77
78         classuse++;
79 }
80
81
82 /*
83  * endpoint destructor
84  */
85 Endpoint::~Endpoint(void)
86 {
87         class Endpoint *temp, **tempp;
88         struct port_list *portlist, *mtemp;
89
90         classuse--;
91
92         /* remote application */
93         if (ep_app)
94                 delete ep_app;
95         
96         /* free relations */
97         if (ep_join_id) {
98                 PERROR("warning: still relation to join.\n");
99         }
100
101         /* free portlist */
102         portlist = ep_portlist;
103         while(portlist) {
104                 if (portlist->port_id) {
105                         PERROR("warning: still relation to port (portlist list)\n");
106                 }
107                 mtemp = portlist;
108                 portlist = portlist->next;
109                 memset(mtemp, 0, sizeof(struct port_list));
110                 FREE(mtemp, sizeof(struct port_list));
111                 ememuse--;
112         }
113
114         /* detach */
115         temp =epoint_first;
116         tempp = &epoint_first;
117         while(temp) {
118                 if (temp == this)
119                         break;
120
121                 tempp = &temp->next;
122                 temp = temp->next;
123         }
124         if (temp == 0)
125                 FATAL("Endpoint not in Endpoint's list.\n");
126         *tempp = next;
127
128         /* free */
129         PDEBUG(DEBUG_EPOINT, "removed endpoint %d.\n", ep_serial);
130 }
131
132 /* create new portlist relation
133  */
134 struct port_list *Endpoint::portlist_new(unsigned int port_id, int port_type, int earlyb)
135 {
136         struct port_list *portlist, **portlistpointer;
137
138         /* portlist structure */
139         portlist = (struct port_list *)MALLOC(sizeof(struct port_list));
140         ememuse++;
141         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocating port_list.\n", ep_serial);
142
143         /* add port_list to chain */
144         portlist->next = NULL;
145         portlistpointer = &ep_portlist;
146         while(*portlistpointer)
147                 portlistpointer = &((*portlistpointer)->next);
148         *portlistpointer = portlist;
149
150         /* link to join or port */
151         portlist->port_id = port_id;
152         portlist->port_type = port_type;
153         portlist->early_b = earlyb;
154
155         return(portlist);
156 }
157
158
159 /* free portlist relation
160  */
161 void Endpoint::free_portlist(struct port_list *portlist)
162 {
163         struct port_list *temp, **tempp;
164
165         temp = ep_portlist;
166         tempp = &ep_portlist;
167         while(temp) {
168                 if (temp == portlist)
169                         break;
170
171                 tempp = &temp->next;
172                 temp = temp->next;
173         }
174         if (!temp)
175                 FATAL("port_list not in Endpoint's list.\n");
176         /* detach */
177         *tempp=portlist->next;
178
179         /* free */
180         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removed port_list from endpoint\n", ep_serial);
181         FREE(portlist, sizeof(struct port_list));
182         ememuse--;
183 }
184
185
186 /* handler for endpoint
187  */
188 int Endpoint::handler(void)
189 {
190         if (ep_use <= 0) {
191                 delete this;
192                 return(-1);
193         }
194
195         /* call application handler */
196         if (ep_app)
197                 return(ep_app->handler());
198         return(0);
199 }