2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * i4b daemon - controller state support routines
28 * ----------------------------------------------
30 * $Id: controller.c,v 1.10 2009/04/16 05:56:32 lukem Exp $
34 * last edit-date: [Mon Oct 9 14:37:34 2000]
36 *---------------------------------------------------------------------------*/
38 #include <sys/types.h>
46 init_controller_state(int controller
, const char *devnam
, const char *cardname
, int tei
, int nbch
);
49 * add a single controller
52 init_new_controller(int isdnif
)
54 msg_ctrl_info_req_t mcir
;
56 memset(&mcir
, 0, sizeof mcir
);
57 mcir
.controller
= isdnif
;
59 if ((ioctl(isdnfd
, I4B_CTRL_INFO_REQ
, &mcir
)) < 0)
62 if ((init_controller_state(isdnif
, mcir
.devname
, mcir
.cardname
, mcir
.tei
, mcir
.nbch
)) == ERROR
)
64 logit(LL_ERR
, "init_new_controller: init_controller_state for controller %d failed", isdnif
);
69 /*---------------------------------------------------------------------------*
70 * init controller state array
71 *---------------------------------------------------------------------------*/
77 msg_ctrl_info_req_t mcir
;
79 remove_all_ctrl_state();
80 for (i
=0; i
<= max
; i
++)
84 if ((ioctl(isdnfd
, I4B_CTRL_INFO_REQ
, &mcir
)) < 0)
87 max
= mcir
.max_isdnif
;
89 /* init controller tab */
91 if ((init_controller_state(i
, mcir
.devname
, mcir
.cardname
, mcir
.tei
, mcir
.nbch
)) == ERROR
)
93 logit(LL_ERR
, "init_controller: init_controller_state for controller %d failed", i
);
97 DBGL(DL_RCCF
, (logit(LL_DBG
, "init_controller: found %d ISDN controller(s)", max
)));
100 /*--------------------------------------------------------------------------*
101 * init controller state table entry
102 *--------------------------------------------------------------------------*/
104 init_controller_state(int controller
, const char *devnam
, const char *cardname
, int tei
, int nbch
)
106 struct isdn_ctrl_state
*ctrl
;
109 ctrl
= malloc(sizeof *ctrl
);
111 logit(LL_ERR
, "init_controller_state: out of memory");
115 /* init controller state entry */
117 memset(ctrl
, 0, sizeof *ctrl
);
118 strncpy(ctrl
->device_name
,
120 sizeof(ctrl
->device_name
)-1);
121 strncpy(ctrl
->controller
,
123 sizeof(ctrl
->controller
)-1);
124 ctrl
->isdnif
= controller
;
125 ctrl
->protocol
= PROTOCOL_DSS1
;
126 ctrl
->state
= CTRL_UP
;
128 for (i
= 0; i
< ctrl
->nbch
; i
++)
129 ctrl
->stateb
[i
] = CHAN_IDLE
;
130 ctrl
->freechans
= MAX_CHANCTRL
;
132 ctrl
->l1stat
= LAYER_IDLE
;
133 ctrl
->l2stat
= LAYER_IDLE
;
134 ctrl
->firmware
= NULL
;
135 DBGL(DL_RCCF
, (logit(LL_DBG
, "init_controller_state: controller %d (%s) is %s",
136 controller
, devnam
, cardname
)));
139 add_ctrl_state(ctrl
);
144 /*--------------------------------------------------------------------------*
145 * init active controller
146 *--------------------------------------------------------------------------*/
148 init_active_controller(void)
150 struct isdn_ctrl_state
*cst
= NULL
;
155 /* XXX - replace by something useful */
157 char cmdbuf
[MAXPATHLEN
+128];
159 for (controller
= 0; controller
< ncontroller
; controller
++)
161 if (isdn_ctrl_tab
[controller
].ctrl_type
== CTRL_TINADD
)
163 DBGL(DL_RCCF
, (logit(LL_DBG
, "init_active_controller, tina-dd %d: executing [%s %d]", unit
, tinainitprog
, unit
)));
165 snprintf(cmdbuf
, sizeof(cmdbuf
), "%s %d", tinainitprog
, unit
);
167 if ((ret
= system(cmdbuf
)) != 0)
169 logit(LL_ERR
, "init_active_controller, tina-dd %d: %s returned %d!", unit
, tinainitprog
, ret
);
176 numctrl
= count_ctrl_states();
177 for (cst
= get_first_ctrl_state(), i
= 0;
179 cst
= find_ctrl_state(i
++)) {
182 * Generic microcode loading. If a controller has
183 * defined a microcode file, load it using the
184 * I4B_CTRL_DOWNLOAD ioctl.
186 if (cst
->firmware
!= NULL
) {
187 struct isdn_dr_prot idp
;
188 struct isdn_download_request idr
;
190 fd
= open(cst
->firmware
, O_RDONLY
);
192 logit(LL_ERR
, "init_active_controller %d: "
193 "open %s: %s!", cst
->isdnif
, cst
->firmware
,
198 idp
.bytecount
= lseek(fd
, 0, SEEK_END
);
199 idp
.microcode
= mmap(0, idp
.bytecount
, PROT_READ
,
201 if (idp
.microcode
== MAP_FAILED
) {
202 logit(LL_ERR
, "init_active_controller %d: "
203 "mmap %s: %s!", cst
->isdnif
, cst
->firmware
,
208 DBGL(DL_RCCF
, (logit(LL_DBG
, "init_active_controller "
209 "%d: loading firmware from [%s]", cst
->isdnif
,
212 idr
.controller
= cst
->isdnif
;
214 idr
.protocols
= &idp
;
216 ret
= ioctl(isdnfd
, I4B_CTRL_DOWNLOAD
, &idr
,
219 logit(LL_ERR
, "init_active_controller %d: "
220 "load %s: %s!", cst
->isdnif
, cst
->firmware
,
225 munmap(idp
.microcode
, idp
.bytecount
);
232 init_single_controller_protocol ( struct isdn_ctrl_state
*ctrl
)
236 memset(&mpi
, 0, sizeof mpi
);
237 mpi
.controller
= ctrl
->isdnif
;
238 mpi
.protocol
= ctrl
->protocol
;
240 if ((ioctl(isdnfd
, I4B_PROT_IND
, &mpi
)) < 0)
242 logit(LL_ERR
, "init_single_controller_protocol: ioctl I4B_PROT_IND failed: %s", strerror(errno
));
247 /*--------------------------------------------------------------------------*
248 * init controller D-channel ISDN protocol
249 *--------------------------------------------------------------------------*/
251 init_controller_protocol(void)
253 struct isdn_ctrl_state
*ctrl
;
255 for (ctrl
= get_first_ctrl_state(); ctrl
; ctrl
= NEXT_CTRL(ctrl
))
256 init_single_controller_protocol(ctrl
);
259 /*--------------------------------------------------------------------------*
260 * set controller state to UP/DOWN
261 *--------------------------------------------------------------------------*/
263 set_controller_state(struct isdn_ctrl_state
*ctrl
, int state
)
266 logit(LL_ERR
, "set_controller_state: invalid controller");
270 if (state
== CTRL_UP
) {
271 ctrl
->state
= CTRL_UP
;
272 DBGL(DL_CNST
, (logit(LL_DBG
, "set_controller_state: controller [%d] set UP!", ctrl
->isdnif
)));
274 else if (state
== CTRL_DOWN
)
276 ctrl
->state
= CTRL_DOWN
;
277 DBGL(DL_CNST
, (logit(LL_DBG
, "set_controller_state: controller [%d] set DOWN!", ctrl
->isdnif
)));
281 logit(LL_ERR
, "set_controller_state: invalid controller state [%d]!", state
);
287 /*--------------------------------------------------------------------------*
288 * get controller state
289 *--------------------------------------------------------------------------*/
291 get_controller_state(struct isdn_ctrl_state
*ctrl
)
294 logit(LL_ERR
, "set_controller_state: invalid controller");
297 return (ctrl
->state
);
300 /*--------------------------------------------------------------------------*
301 * decrement number of free channels for controller
302 *--------------------------------------------------------------------------*/
304 decr_free_channels(struct isdn_ctrl_state
*ctrl
)
307 logit(LL_ERR
, "decr_free_channels: invalid controller!");
310 if (ctrl
->freechans
> 0)
313 DBGL(DL_CNST
, (logit(LL_DBG
, "decr_free_channels: ctrl %d, now %d chan free", ctrl
->isdnif
, ctrl
->freechans
)));
318 logit(LL_ERR
, "decr_free_channels: controller [%d] already 0 free chans!", ctrl
->isdnif
);
323 /*--------------------------------------------------------------------------*
324 * increment number of free channels for controller
325 *--------------------------------------------------------------------------*/
327 incr_free_channels(struct isdn_ctrl_state
*ctrl
)
330 logit(LL_ERR
, "incr_free_channels: invalid controller!");
333 if (ctrl
->freechans
< MAX_CHANCTRL
)
336 DBGL(DL_CNST
, (logit(LL_DBG
, "incr_free_channels: ctrl %d, now %d chan free", ctrl
->isdnif
, ctrl
->freechans
)));
341 logit(LL_ERR
, "incr_free_channels: controller [%d] already 2 free chans!", ctrl
->isdnif
);
346 /*--------------------------------------------------------------------------*
347 * get number of free channels for controller
348 *--------------------------------------------------------------------------*/
350 get_free_channels(struct isdn_ctrl_state
*ctrl
)
353 logit(LL_ERR
, "get_free_channels: invalid controller!");
356 DBGL(DL_CNST
, (logit(LL_DBG
, "get_free_channels: ctrl %d, %d chan free", ctrl
->isdnif
, ctrl
->freechans
)));
357 return (ctrl
->freechans
);
360 /*--------------------------------------------------------------------------*
361 * set channel state to busy
362 *--------------------------------------------------------------------------*/
364 set_channel_busy(struct isdn_ctrl_state
*ctrl
, int channel
)
367 logit(LL_ERR
, "set_channel_busy: invalid controller");
371 if (channel
< 0 || channel
>= ctrl
->nbch
)
373 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_busy: controller [%d] invalid channel %d", ctrl
->isdnif
, channel
)));
377 if (ctrl
->stateb
[channel
] == CHAN_RUN
)
379 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_busy: controller [%d] channel B%d already busy!", ctrl
->isdnif
, channel
)));
383 ctrl
->stateb
[channel
] = CHAN_RUN
;
384 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_busy: controller [%d] channel B%d set to BUSY!", ctrl
->isdnif
, channel
)));
390 /*--------------------------------------------------------------------------*
391 * set channel state to idle
392 *--------------------------------------------------------------------------*/
394 set_channel_idle(struct isdn_ctrl_state
*ctrl
, int channel
)
397 logit(LL_ERR
, "set_channel_idle: invalid controller");
401 if (channel
< 0 || channel
>= ctrl
->nbch
)
403 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_idle: controller [%d] invalid channel %d", ctrl
->isdnif
, channel
)));
407 if (ctrl
->stateb
[channel
] == CHAN_IDLE
)
409 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_idle: controller [%d] channel B%d already idle!", ctrl
->isdnif
, channel
)));
413 ctrl
->stateb
[channel
] = CHAN_IDLE
;
414 DBGL(DL_CNST
, (logit(LL_DBG
, "set_channel_idle: controller [%d] channel B%d set to IDLE!", ctrl
->isdnif
, channel
)));
420 /*--------------------------------------------------------------------------*
421 * return channel state
422 *--------------------------------------------------------------------------*/
424 ret_channel_state(struct isdn_ctrl_state
*ctrl
, int channel
)
427 logit(LL_ERR
, "ret_channel_state: invalid controller!");
431 if (channel
< 0 || channel
>= ctrl
->nbch
) {
432 logit(LL_ERR
, "ret_channel_state: controller [%d], invalid channel [%d]!", ctrl
->isdnif
, channel
);
437 return (ctrl
->stateb
[channel
]);