1/* 2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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 23 * SUCH DAMAGE. 24 * 25 *--------------------------------------------------------------------------- 26 * 27 * i4b daemon - controller state support routines 28 * ---------------------------------------------- 29 * 30 * $Id: controller.c,v 1.10 2009/04/16 05:56:32 lukem Exp $ 31 * 32 * $FreeBSD$ 33 * 34 * last edit-date: [Mon Oct 9 14:37:34 2000] 35 * 36 *---------------------------------------------------------------------------*/ 37 38#include <sys/types.h> 39#include <sys/mman.h> 40 41#include <fcntl.h> 42 43#include "isdnd.h" 44 45static int 46init_controller_state(int controller, const char *devnam, const char *cardname, int tei, int nbch); 47 48/* 49 * add a single controller 50 */ 51void 52init_new_controller(int isdnif) 53{ 54 msg_ctrl_info_req_t mcir; 55 56 memset(&mcir, 0, sizeof mcir); 57 mcir.controller = isdnif; 58 59 if ((ioctl(isdnfd, I4B_CTRL_INFO_REQ, &mcir)) < 0) 60 return; 61 62 if ((init_controller_state(isdnif, mcir.devname, mcir.cardname, mcir.tei, mcir.nbch)) == ERROR) 63 { 64 logit(LL_ERR, "init_new_controller: init_controller_state for controller %d failed", isdnif); 65 do_exit(1); 66 } 67} 68 69/*---------------------------------------------------------------------------* 70 * init controller state array 71 *---------------------------------------------------------------------------*/ 72void 73init_controller(void) 74{ 75 int i; 76 int max = 0; 77 msg_ctrl_info_req_t mcir; 78 79 remove_all_ctrl_state(); 80 for (i=0; i <= max; i++) 81 { 82 mcir.controller = i; 83 84 if ((ioctl(isdnfd, I4B_CTRL_INFO_REQ, &mcir)) < 0) 85 continue; 86 87 max = mcir.max_isdnif; 88 89 /* init controller tab */ 90 91 if ((init_controller_state(i, mcir.devname, mcir.cardname, mcir.tei, mcir.nbch)) == ERROR) 92 { 93 logit(LL_ERR, "init_controller: init_controller_state for controller %d failed", i); 94 do_exit(1); 95 } 96 } 97 DBGL(DL_RCCF, (logit(LL_DBG, "init_controller: found %d ISDN controller(s)", max))); 98} 99 100/*--------------------------------------------------------------------------* 101 * init controller state table entry 102 *--------------------------------------------------------------------------*/ 103static int 104init_controller_state(int controller, const char *devnam, const char *cardname, int tei, int nbch) 105{ 106 struct isdn_ctrl_state *ctrl; 107 int i; 108 109 ctrl = malloc(sizeof *ctrl); 110 if (ctrl == NULL) { 111 logit(LL_ERR, "init_controller_state: out of memory"); 112 return(ERROR); 113 } 114 115 /* init controller state entry */ 116 117 memset(ctrl, 0, sizeof *ctrl); 118 strncpy(ctrl->device_name, 119 devnam, 120 sizeof(ctrl->device_name)-1); 121 strncpy(ctrl->controller, 122 cardname, 123 sizeof(ctrl->controller)-1); 124 ctrl->isdnif = controller; 125 ctrl->protocol = PROTOCOL_DSS1; 126 ctrl->state = CTRL_UP; 127 ctrl->nbch = nbch; 128 for (i = 0; i < ctrl->nbch; i++) 129 ctrl->stateb[i] = CHAN_IDLE; 130 ctrl->freechans = MAX_CHANCTRL; 131 ctrl->tei = tei; 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))); 137 138 /* add to list */ 139 add_ctrl_state(ctrl); 140 141 return(GOOD); 142} 143 144/*--------------------------------------------------------------------------* 145 * init active controller 146 *--------------------------------------------------------------------------*/ 147void 148init_active_controller(void) 149{ 150 struct isdn_ctrl_state *cst = NULL; 151 int ret, fd; 152 int i, numctrl; 153 154#if 0 155 /* XXX - replace by something useful */ 156 int controller; 157 char cmdbuf[MAXPATHLEN+128]; 158 159 for (controller = 0; controller < ncontroller; controller++) 160 { 161 if (isdn_ctrl_tab[controller].ctrl_type == CTRL_TINADD) 162 { 163 DBGL(DL_RCCF, (logit(LL_DBG, "init_active_controller, tina-dd %d: executing [%s %d]", unit, tinainitprog, unit))); 164 165 snprintf(cmdbuf, sizeof(cmdbuf), "%s %d", tinainitprog, unit); 166 167 if ((ret = system(cmdbuf)) != 0) 168 { 169 logit(LL_ERR, "init_active_controller, tina-dd %d: %s returned %d!", unit, tinainitprog, ret); 170 do_exit(1); 171 } 172 } 173 } 174#endif 175 176 numctrl = count_ctrl_states(); 177 for (cst = get_first_ctrl_state(), i = 0; 178 i < numctrl; 179 cst = find_ctrl_state(i++)) { 180 181 /* 182 * Generic microcode loading. If a controller has 183 * defined a microcode file, load it using the 184 * I4B_CTRL_DOWNLOAD ioctl. 185 */ 186 if (cst->firmware != NULL) { 187 struct isdn_dr_prot idp; 188 struct isdn_download_request idr; 189 190 fd = open(cst->firmware, O_RDONLY); 191 if (fd < 0) { 192 logit(LL_ERR, "init_active_controller %d: " 193 "open %s: %s!", cst->isdnif, cst->firmware, 194 strerror(errno)); 195 do_exit(1); 196 } 197 198 idp.bytecount = lseek(fd, 0, SEEK_END); 199 idp.microcode = mmap(0, idp.bytecount, PROT_READ, 200 MAP_SHARED, fd, 0); 201 if (idp.microcode == MAP_FAILED) { 202 logit(LL_ERR, "init_active_controller %d: " 203 "mmap %s: %s!", cst->isdnif, cst->firmware, 204 strerror(errno)); 205 do_exit(1); 206 } 207 208 DBGL(DL_RCCF, (logit(LL_DBG, "init_active_controller " 209 "%d: loading firmware from [%s]", cst->isdnif, 210 cst->firmware))); 211 212 idr.controller = cst->isdnif; 213 idr.numprotos = 1; 214 idr.protocols = &idp; 215 216 ret = ioctl(isdnfd, I4B_CTRL_DOWNLOAD, &idr, 217 sizeof(idr)); 218 if (ret) { 219 logit(LL_ERR, "init_active_controller %d: " 220 "load %s: %s!", cst->isdnif, cst->firmware, 221 strerror(errno)); 222 do_exit(1); 223 } 224 225 munmap(idp.microcode, idp.bytecount); 226 close(fd); 227 } 228 } 229} 230 231void 232init_single_controller_protocol ( struct isdn_ctrl_state *ctrl ) 233{ 234 msg_prot_ind_t mpi; 235 236 memset(&mpi, 0, sizeof mpi); 237 mpi.controller = ctrl->isdnif; 238 mpi.protocol = ctrl->protocol; 239 240 if ((ioctl(isdnfd, I4B_PROT_IND, &mpi)) < 0) 241 { 242 logit(LL_ERR, "init_single_controller_protocol: ioctl I4B_PROT_IND failed: %s", strerror(errno)); 243 do_exit(1); 244 } 245} 246 247/*--------------------------------------------------------------------------* 248 * init controller D-channel ISDN protocol 249 *--------------------------------------------------------------------------*/ 250void 251init_controller_protocol(void) 252{ 253 struct isdn_ctrl_state *ctrl; 254 255 for (ctrl = get_first_ctrl_state(); ctrl; ctrl = NEXT_CTRL(ctrl)) 256 init_single_controller_protocol(ctrl); 257} 258 259/*--------------------------------------------------------------------------* 260 * set controller state to UP/DOWN 261 *--------------------------------------------------------------------------*/ 262int 263set_controller_state(struct isdn_ctrl_state *ctrl, int state) 264{ 265 if (ctrl == NULL) { 266 logit(LL_ERR, "set_controller_state: invalid controller"); 267 return(ERROR); 268 } 269 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))); 273 } 274 else if (state == CTRL_DOWN) 275 { 276 ctrl->state = CTRL_DOWN; 277 DBGL(DL_CNST, (logit(LL_DBG, "set_controller_state: controller [%d] set DOWN!", ctrl->isdnif))); 278 } 279 else 280 { 281 logit(LL_ERR, "set_controller_state: invalid controller state [%d]!", state); 282 return(ERROR); 283 } 284 return(GOOD); 285} 286 287/*--------------------------------------------------------------------------* 288 * get controller state 289 *--------------------------------------------------------------------------*/ 290int 291get_controller_state(struct isdn_ctrl_state *ctrl) 292{ 293 if (ctrl == NULL) { 294 logit(LL_ERR, "set_controller_state: invalid controller"); 295 return(ERROR); 296 } 297 return (ctrl->state); 298} 299 300/*--------------------------------------------------------------------------* 301 * decrement number of free channels for controller 302 *--------------------------------------------------------------------------*/ 303int 304decr_free_channels(struct isdn_ctrl_state *ctrl) 305{ 306 if (ctrl == NULL) { 307 logit(LL_ERR, "decr_free_channels: invalid controller!"); 308 return(ERROR); 309 } 310 if (ctrl->freechans > 0) 311 { 312 ctrl->freechans--; 313 DBGL(DL_CNST, (logit(LL_DBG, "decr_free_channels: ctrl %d, now %d chan free", ctrl->isdnif, ctrl->freechans))); 314 return(GOOD); 315 } 316 else 317 { 318 logit(LL_ERR, "decr_free_channels: controller [%d] already 0 free chans!", ctrl->isdnif); 319 return(ERROR); 320 } 321} 322 323/*--------------------------------------------------------------------------* 324 * increment number of free channels for controller 325 *--------------------------------------------------------------------------*/ 326int 327incr_free_channels(struct isdn_ctrl_state *ctrl) 328{ 329 if (ctrl == NULL) { 330 logit(LL_ERR, "incr_free_channels: invalid controller!"); 331 return(ERROR); 332 } 333 if (ctrl->freechans < MAX_CHANCTRL) 334 { 335 ctrl->freechans++; 336 DBGL(DL_CNST, (logit(LL_DBG, "incr_free_channels: ctrl %d, now %d chan free", ctrl->isdnif, ctrl->freechans))); 337 return(GOOD); 338 } 339 else 340 { 341 logit(LL_ERR, "incr_free_channels: controller [%d] already 2 free chans!", ctrl->isdnif); 342 return(ERROR); 343 } 344} 345 346/*--------------------------------------------------------------------------* 347 * get number of free channels for controller 348 *--------------------------------------------------------------------------*/ 349int 350get_free_channels(struct isdn_ctrl_state *ctrl) 351{ 352 if (ctrl == NULL) { 353 logit(LL_ERR, "get_free_channels: invalid controller!"); 354 return(ERROR); 355 } 356 DBGL(DL_CNST, (logit(LL_DBG, "get_free_channels: ctrl %d, %d chan free", ctrl->isdnif, ctrl->freechans))); 357 return (ctrl->freechans); 358} 359 360/*--------------------------------------------------------------------------* 361 * set channel state to busy 362 *--------------------------------------------------------------------------*/ 363int 364set_channel_busy(struct isdn_ctrl_state *ctrl, int channel) 365{ 366 if (ctrl == NULL) { 367 logit(LL_ERR, "set_channel_busy: invalid controller"); 368 return(ERROR); 369 } 370 371 if (channel < 0 || channel >= ctrl->nbch) 372 { 373 DBGL(DL_CNST, (logit(LL_DBG, "set_channel_busy: controller [%d] invalid channel %d", ctrl->isdnif, channel))); 374 return(ERROR); 375 } 376 377 if (ctrl->stateb[channel] == CHAN_RUN) 378 { 379 DBGL(DL_CNST, (logit(LL_DBG, "set_channel_busy: controller [%d] channel B%d already busy!", ctrl->isdnif, channel))); 380 } 381 else 382 { 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))); 385 } 386 387 return(GOOD); 388} 389 390/*--------------------------------------------------------------------------* 391 * set channel state to idle 392 *--------------------------------------------------------------------------*/ 393int 394set_channel_idle(struct isdn_ctrl_state *ctrl, int channel) 395{ 396 if (ctrl == NULL) { 397 logit(LL_ERR, "set_channel_idle: invalid controller"); 398 return(ERROR); 399 } 400 401 if (channel < 0 || channel >= ctrl->nbch) 402 { 403 DBGL(DL_CNST, (logit(LL_DBG, "set_channel_idle: controller [%d] invalid channel %d", ctrl->isdnif, channel))); 404 return(ERROR); 405 } 406 407 if (ctrl->stateb[channel] == CHAN_IDLE) 408 { 409 DBGL(DL_CNST, (logit(LL_DBG, "set_channel_idle: controller [%d] channel B%d already idle!", ctrl->isdnif, channel))); 410 } 411 else 412 { 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))); 415 } 416 417 return(GOOD); 418} 419 420/*--------------------------------------------------------------------------* 421 * return channel state 422 *--------------------------------------------------------------------------*/ 423int 424ret_channel_state(struct isdn_ctrl_state *ctrl, int channel) 425{ 426 if (ctrl == NULL) { 427 logit(LL_ERR, "ret_channel_state: invalid controller!"); 428 return(ERROR); 429 } 430 431 if (channel < 0 || channel >= ctrl->nbch) { 432 logit(LL_ERR, "ret_channel_state: controller [%d], invalid channel [%d]!", ctrl->isdnif, channel); 433 return(ERROR); 434 } 435 else 436 { 437 return (ctrl->stateb[channel]); 438 } 439} 440 441/* EOF */ 442