/* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $ * * Kernel CAPI 2.0 Module * * Copyright 1999 by Carsten Paeth <calle@calle.de> * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name> * * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. *
*/
staticinlineint capi_cmd_valid(u8 cmd)
{ switch (cmd) { case CAPI_ALERT: case CAPI_CONNECT: case CAPI_CONNECT_ACTIVE: case CAPI_CONNECT_B3_ACTIVE: case CAPI_CONNECT_B3: case CAPI_CONNECT_B3_T90_ACTIVE: case CAPI_DATA_B3: case CAPI_DISCONNECT_B3: case CAPI_DISCONNECT: case CAPI_FACILITY: case CAPI_INFO: case CAPI_LISTEN: case CAPI_MANUFACTURER: case CAPI_RESET_B3: case CAPI_SELECT_B_PROTOCOL: return 1;
} return 0;
}
staticinlineint capi_subcmd_valid(u8 subcmd)
{ switch (subcmd) { case CAPI_REQ: case CAPI_CONF: case CAPI_IND: case CAPI_RESP: return 1;
} return 0;
}
rcu_read_lock();
ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); if (!ap) {
rcu_read_unlock();
cdb = capi_message2str(skb->data); if (cdb) {
printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
CAPIMSG_APPID(skb->data), cdb->buf);
cdebbuf_free(cdb);
} else
printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
CAPIMSG_APPID(skb->data),
capi_cmd2str(cmd, subcmd)); goto error;
}
skb_queue_tail(&ap->recv_queue, skb);
queue_work(kcapi_wq, &ap->recv_work);
rcu_read_unlock();
return;
error:
kfree_skb(skb);
}
EXPORT_SYMBOL(capi_ctr_handle_message);
/** * capi_ctr_ready() - signal CAPI controller ready * @ctr: controller descriptor structure. * * Called by hardware driver to signal that the controller is up and running.
*/
/** * capi_ctr_down() - signal CAPI controller not ready * @ctr: controller descriptor structure. * * Called by hardware driver to signal that the controller is down and * unavailable for use.
*/
/** * attach_capi_ctr() - register CAPI controller * @ctr: controller descriptor structure. * * Called by hardware driver to register a controller with the CAPI subsystem. * Return value: 0 on success, error code < 0 on error
*/
int attach_capi_ctr(struct capi_ctr *ctr)
{ int i;
mutex_lock(&capi_controller_lock);
for (i = 0; i < CAPI_MAXCONTR; i++) { if (!capi_controller[i]) break;
} if (i == CAPI_MAXCONTR) {
mutex_unlock(&capi_controller_lock);
printk(KERN_ERR "kcapi: out of controller slots\n"); return -EBUSY;
}
capi_controller[i] = ctr;
/** * detach_capi_ctr() - unregister CAPI controller * @ctr: controller descriptor structure. * * Called by hardware driver to remove the registration of a controller * with the CAPI subsystem. * Return value: 0 on success, error code < 0 on error
*/
int detach_capi_ctr(struct capi_ctr *ctr)
{ int err = 0;
/** * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED * * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller * is ready for use, CAPI_REGNOTINSTALLED otherwise)
*/
u16 capi20_isinstalled(void)
{
u16 ret = CAPI_REGNOTINSTALLED; int i;
mutex_lock(&capi_controller_lock);
for (i = 0; i < CAPI_MAXCONTR; i++) if (capi_controller[i] &&
capi_controller[i]->state == CAPI_CTR_RUNNING) {
ret = CAPI_NOERROR; break;
}
mutex_unlock(&capi_controller_lock);
return ret;
}
/** * capi20_register() - CAPI 2.0 operation CAPI_REGISTER * @ap: CAPI application descriptor structure. * * Register an application's presence with CAPI. * A unique application ID is assigned and stored in @ap->applid. * After this function returns successfully, the message receive * callback function @ap->recv_message() may be called at any time * until capi20_release() has been called for the same @ap. * Return value: CAPI result code
*/
u16 capi20_register(struct capi20_appl *ap)
{ int i;
u16 applid;
DBG("");
if (ap->rparam.datablklen < 128) return CAPI_LOGBLKSIZETOSMALL;
for (i = 0; i < CAPI_MAXCONTR; i++) { if (!capi_controller[i] ||
capi_controller[i]->state != CAPI_CTR_RUNNING) continue;
register_appl(capi_controller[i], applid, &ap->rparam);
}
/** * capi20_release() - CAPI 2.0 operation CAPI_RELEASE * @ap: CAPI application descriptor structure. * * Terminate an application's registration with CAPI. * After this function returns successfully, the message receive * callback function @ap->recv_message() will no longer be called. * Return value: CAPI result code
*/
u16 capi20_release(struct capi20_appl *ap)
{ int i;
for (i = 0; i < CAPI_MAXCONTR; i++) { if (!capi_controller[i] ||
capi_controller[i]->state != CAPI_CTR_RUNNING) continue;
release_appl(capi_controller[i], ap->applid);
}
if (ncontrollers == 0) return CAPI_REGNOTINSTALLED; if ((ap->applid == 0) || ap->release_in_progress) return CAPI_ILLAPPNR; if (skb->len < 12
|| !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
|| !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
/* * The controller reference is protected by the existence of the * application passed to us. We assume that the caller properly * synchronizes this service with capi20_release.
*/
ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); if (!ctr || ctr->state != CAPI_CTR_RUNNING) return CAPI_REGNOTINSTALLED; if (ctr->blocked) return CAPI_SENDQUEUEFULL;
/** * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER * @contr: controller number. * @serial: result buffer (8 bytes). * * Retrieve the serial number of the specified ISDN controller * or (for @contr == 0) the driver itself. * Return value: CAPI result code
*/
/** * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE * @contr: controller number. * @profp: result structure. * * Retrieve capability information for the specified ISDN controller * or (for @contr == 0) the number of installed controllers. * Return value: CAPI result code
*/
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.