fixed trace bug
[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         {
28 //printf("comparing: '%s' with '%s'\n", name, epoint->name);
29                 if (epoint->ep_serial == epoint_id)
30                         return(epoint);
31                 epoint = epoint->next;
32         }
33
34         return(NULL);
35 }
36
37
38 /*
39  * endpoint constructor (link with either port or join id)
40  */
41 Endpoint::Endpoint(unsigned int port_id, unsigned int join_id)
42 {
43         class Port *port;
44         class Endpoint **epointpointer;
45         int earlyb = 0;
46
47         /* epoint structure */
48         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":"");
49
50         ep_portlist = NULL;
51         ep_app = NULL;
52         ep_use = 1;
53
54         /* add endpoint to chain */
55         next = NULL;
56         epointpointer = &epoint_first;
57         while(*epointpointer)
58                 epointpointer = &((*epointpointer)->next);
59         *epointpointer = this;
60
61         /* serial */
62         ep_serial = epoint_serial++;
63
64         /* link to join or port */
65         if (port_id)
66         {
67                 port = find_port_id(port_id);
68                 if (port)
69                 {
70                         if ((port->p_type&PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1)
71                                 earlyb = ((class PmISDN *)port)->p_m_mISDNport->earlyb;
72                         if (!portlist_new(port_id, port->p_type, earlyb))
73                                 FATAL("No memory for portlist.\n");
74                 }
75         }
76         ep_join_id = join_id;
77
78         ep_park = 0;
79         ep_park_len = 0;
80
81         classuse++;
82 }
83
84
85 /*
86  * endpoint destructor
87  */
88 Endpoint::~Endpoint(void)
89 {
90         class Endpoint *temp, **tempp;
91         struct port_list *portlist, *mtemp;
92
93         classuse--;
94
95         /* remote application */
96         if (ep_app)
97                 delete ep_app;
98         
99         /* free relations */
100         if (ep_join_id)
101         {
102                 PERROR("warning: still relation to join.\n");
103         }
104
105         /* free portlist */
106         portlist = ep_portlist;
107         while(portlist)
108         {
109                 if (portlist->port_id)
110                 {
111                         PERROR("warning: still relation to port (portlist list)\n");
112                 }
113                 mtemp = portlist;
114                 portlist = portlist->next;
115                 memset(mtemp, 0, sizeof(struct port_list));
116                 FREE(mtemp, sizeof(struct port_list));
117                 ememuse--;
118         }
119
120         /* detach */
121         temp =epoint_first;
122         tempp = &epoint_first;
123         while(temp)
124         {
125                 if (temp == this)
126                         break;
127
128                 tempp = &temp->next;
129                 temp = temp->next;
130         }
131         if (temp == 0)
132                 FATAL("Endpoint not in Endpoint's list.\n");
133         *tempp = next;
134
135         /* free */
136         PDEBUG(DEBUG_EPOINT, "removed endpoint %d.\n", ep_serial);
137 }
138
139 /* create new portlist relation
140  */
141 struct port_list *Endpoint::portlist_new(unsigned int port_id, int port_type, int earlyb)
142 {
143         struct port_list *portlist, **portlistpointer;
144
145         /* portlist structure */
146         portlist = (struct port_list *)MALLOC(sizeof(struct port_list));
147         ememuse++;
148         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocating port_list.\n", ep_serial);
149
150         /* add port_list to chain */
151         portlist->next = NULL;
152         portlistpointer = &ep_portlist;
153         while(*portlistpointer)
154                 portlistpointer = &((*portlistpointer)->next);
155         *portlistpointer = portlist;
156
157         /* link to join or port */
158         portlist->port_id = port_id;
159         portlist->port_type = port_type;
160         portlist->early_b = earlyb;
161
162         return(portlist);
163 }
164
165
166 /* free portlist relation
167  */
168 void Endpoint::free_portlist(struct port_list *portlist)
169 {
170         struct port_list *temp, **tempp;
171
172         temp = ep_portlist;
173         tempp = &ep_portlist;
174         while(temp)
175         {
176                 if (temp == portlist)
177                         break;
178
179                 tempp = &temp->next;
180                 temp = temp->next;
181         }
182         if (!temp)
183                 FATAL("port_list not in Endpoint's list.\n");
184         /* detach */
185         *tempp=portlist->next;
186
187         /* free */
188         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removed port_list from endpoint\n", ep_serial);
189         FREE(portlist, sizeof(struct port_list));
190         ememuse--;
191 }
192
193
194 /* handler for endpoint
195  */
196 int Endpoint::handler(void)
197 {
198         if (ep_use <= 0)
199         {
200                 delete this;
201                 return(-1);
202         }
203
204         /* call application handler */
205         if (ep_app)
206                 return(ep_app->handler());
207         return(0);
208 }