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