backup
[lcr.git] / endpoint.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** The Endpoint is the link between the call 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 call id)
41  */
42 Endpoint::Endpoint(int port_id, int call_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":"", (call_id)?" call":"");
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 call 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->is_earlyb;
73                         if (!portlist_new(port_id, port->p_type, earlyb))
74                         {
75                                 PERROR("no mem for portlist, exitting...\n");
76                                 exit(-1);
77                         }
78                 }
79         }
80         ep_call_id = call_id;
81
82         ep_park = 0;
83         ep_park_len = 0;
84
85         classuse++;
86 }
87
88
89 /*
90  * endpoint destructor
91  */
92 Endpoint::~Endpoint(void)
93 {
94         class Endpoint *temp, **tempp;
95         struct port_list *portlist, *mtemp;
96
97         classuse--;
98
99         /* remote application */
100         if (ep_app)
101                 delete ep_app;
102         
103         /* free relations */
104         if (ep_call_id)
105         {
106                 PERROR("warning: still relation to call.\n");
107         }
108
109         /* free portlist */
110         portlist = ep_portlist;
111         while(portlist)
112         {
113                 if (portlist->port_id)
114                 {
115                         PERROR("warning: still relation to port (portlist list)\n");
116                 }
117                 mtemp = portlist;
118                 portlist = portlist->next;
119                 memset(mtemp, 0, sizeof(struct port_list));
120                 free(mtemp);
121                 ememuse--;
122         }
123
124         /* detach */
125         temp =epoint_first;
126         tempp = &epoint_first;
127         while(temp)
128         {
129                 if (temp == this)
130                         break;
131
132                 tempp = &temp->next;
133                 temp = temp->next;
134         }
135         if (temp == 0)
136         {
137                 PERROR("error: endpoint not in endpoint's list, exitting.\n");
138                 exit(-1);
139         }
140         *tempp = next;
141
142         /* free */
143         PDEBUG(DEBUG_EPOINT, "removed endpoint %d.\n", ep_serial);
144 }
145
146 /* create new portlist relation
147  */
148 struct port_list *Endpoint::portlist_new(unsigned long port_id, int port_type, int earlyb)
149 {
150         struct port_list *portlist, **portlistpointer;
151
152         /* portlist structure */
153         portlist = (struct port_list *)calloc(1, sizeof(struct port_list));
154         if (!portlist)
155         {
156                 PERROR("no mem for allocating port_list\n");
157                 return(0);
158         }
159         ememuse++;
160         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) allocating port_list.\n", ep_serial);
161         memset(portlist, 0, sizeof(struct port_list));
162
163         /* add port_list to chain */
164         portlist->next = NULL;
165         portlistpointer = &ep_portlist;
166         while(*portlistpointer)
167                 portlistpointer = &((*portlistpointer)->next);
168         *portlistpointer = portlist;
169
170         /* link to call or port */
171         portlist->port_id = port_id;
172         portlist->port_type = port_type;
173         portlist->early_b = earlyb;
174
175         return(portlist);
176 }
177
178
179 /* free portlist relation
180  */
181 void Endpoint::free_portlist(struct port_list *portlist)
182 {
183         struct port_list *temp, **tempp;
184
185         temp = ep_portlist;
186         tempp = &ep_portlist;
187         while(temp)
188         {
189                 if (temp == portlist)
190                         break;
191
192                 tempp = &temp->next;
193                 temp = temp->next;
194         }
195         if (temp == 0)
196         {
197                 PERROR("port_list not in endpoint's list, exitting.\n");
198                 exit(-1);
199         }
200         /* detach */
201         *tempp=portlist->next;
202
203         /* free */
204         PDEBUG(DEBUG_EPOINT, "EPOINT(%d) removed port_list from endpoint\n", ep_serial);
205         memset(portlist, 0, sizeof(struct port_list));
206         free(portlist);
207         ememuse--;
208 }
209
210
211 /* handler for endpoint
212  */
213 int Endpoint::handler(void)
214 {
215         if (ep_use <= 0)
216         {
217                 delete this;
218                 return(-1);
219         }
220
221         /* call application handler */
222         if (ep_app)
223                 return(ep_app->handler());
224         return(0);
225 }