📄 capifunc.c
字号:
card->remove_in_progress = 1; list_del(tmp); break; } } diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card"); if (card) { /* * Detach CAPI. Sendf cannot call to CAPI any more. * After detach no call to send_message() is done too. */ detach_capi_ctr(&card->capi_ctrl); /* * Now get API lock (to ensure stable state of LI tables) * and update the adapter map/LI table. */ diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card"); clean_adapter(card->Id - 1, &free_mem_q); DBG_TRC(("DelAdapterMap (%d) -> (%d)", ControllerMap[card->Id], card->Id)) ControllerMap[card->Id] = 0; DBG_TRC(("adapter remove, max_adapter=%d", max_adapter)); diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card"); /* After releasing the lock, we can free the memory */ diva_os_free (0, card); } /* free queued memory areas */ list_for_each_safe(link, tmp, &free_mem_q) { list_del(link); diva_os_free(0, link); }}/* * remove cards */static void divacapi_remove_cards(void){ DESCRIPTOR d; struct list_head *tmp; diva_card *card; diva_os_spin_lock_magic_t old_irql;rescan: diva_os_enter_spin_lock(&api_lock, &old_irql, "remove cards"); list_for_each(tmp, &cards) { card = list_entry(tmp, diva_card, list); diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards"); d.request = card->d.request; divacapi_remove_card(&d); goto rescan; } diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");}/* * sync_callback */static void sync_callback(ENTITY * e){ diva_os_spin_lock_magic_t old_irql; DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind)) diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback"); callback(e); diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback");}/* * add a new card */static int diva_add_card(DESCRIPTOR * d){ int k = 0, i = 0; diva_os_spin_lock_magic_t old_irql; diva_card *card = NULL; struct capi_ctr *ctrl = NULL; DIVA_CAPI_ADAPTER *a = NULL; IDI_SYNC_REQ sync_req; char serial[16]; void* mem_to_free; LI_CONFIG *new_li_config_table; int j; if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) { DBG_ERR(("diva_add_card: failed to allocate card struct.")) return (0); } memset((char *) card, 0x00, sizeof(diva_card)); memcpy(&card->d, d, sizeof(DESCRIPTOR)); sync_req.GetName.Req = 0; sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME; card->d.request((ENTITY *) & sync_req); strlcpy(card->name, sync_req.GetName.name, sizeof(card->name)); ctrl = &card->capi_ctrl; strcpy(ctrl->name, card->name); ctrl->register_appl = diva_register_appl; ctrl->release_appl = diva_release_appl; ctrl->send_message = diva_send_message; ctrl->procinfo = diva_procinfo; ctrl->driverdata = card; diva_os_set_controller_struct(ctrl); if (attach_capi_ctr(ctrl)) { DBG_ERR(("diva_add_card: failed to attach controller.")) diva_os_free(0, card); return (0); } diva_os_enter_spin_lock(&api_lock, &old_irql, "find id"); card->Id = find_free_id(); diva_os_leave_spin_lock(&api_lock, &old_irql, "find id"); strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu)); ctrl->version.majorversion = 2; ctrl->version.minorversion = 0; ctrl->version.majormanuversion = DRRELMAJOR; ctrl->version.minormanuversion = DRRELMINOR; sync_req.GetSerial.Req = 0; sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL; sync_req.GetSerial.serial = 0; card->d.request((ENTITY *) & sync_req); if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) { sprintf(serial, "%ld-%d", sync_req.GetSerial.serial & 0x00ffffff, i + 1); } else { sprintf(serial, "%ld", sync_req.GetSerial.serial); } serial[CAPI_SERIAL_LEN - 1] = 0; strlcpy(ctrl->serial, serial, sizeof(ctrl->serial)); a = &adapter[card->Id - 1]; card->adapter = a; a->os_card = card; ControllerMap[card->Id] = (byte) (ctrl->cnr); DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id)) sync_req.xdi_capi_prms.Req = 0; sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS; sync_req.xdi_capi_prms.info.structure_length = sizeof(diva_xdi_get_capi_parameters_t); card->d.request((ENTITY *) & sync_req); a->flag_dynamic_l1_down = sync_req.xdi_capi_prms.info.flag_dynamic_l1_down; a->group_optimization_enabled = sync_req.xdi_capi_prms.info.group_optimization_enabled; a->request = DIRequest; /* card->d.request; */ a->max_plci = card->d.channels + 30; a->max_listen = (card->d.channels > 2) ? 8 : 2; if (! (a->plci = (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) { DBG_ERR(("diva_add_card: failed alloc plci struct.")) memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); return (0); } memset(a->plci, 0, sizeof(PLCI) * a->max_plci); for (k = 0; k < a->max_plci; k++) { a->Id = (byte) card->Id; a->plci[k].Sig.callback = sync_callback; a->plci[k].Sig.XNum = 1; a->plci[k].Sig.X = a->plci[k].XData; a->plci[k].Sig.user[0] = (word) (card->Id - 1); a->plci[k].Sig.user[1] = (word) k; a->plci[k].NL.callback = sync_callback; a->plci[k].NL.XNum = 1; a->plci[k].NL.X = a->plci[k].XData; a->plci[k].NL.user[0] = (word) ((card->Id - 1) | 0x8000); a->plci[k].NL.user[1] = (word) k; a->plci[k].adapter = a; } a->profile.Number = card->Id; a->profile.Channels = card->d.channels; if (card->d.features & DI_FAX3) { a->profile.Global_Options = 0x71; if (card->d.features & DI_CODEC) a->profile.Global_Options |= 0x6;#if IMPLEMENT_DTMF a->profile.Global_Options |= 0x8;#endif /* IMPLEMENT_DTMF */ a->profile.Global_Options |= 0x80; /* Line Interconnect */#if IMPLEMENT_ECHO_CANCELLER a->profile.Global_Options |= 0x100;#endif /* IMPLEMENT_ECHO_CANCELLER */ a->profile.B1_Protocols = 0xdf; a->profile.B2_Protocols = 0x1fdb; a->profile.B3_Protocols = 0xb7; a->manufacturer_features = MANUFACTURER_FEATURE_HARDDTMF; } else { a->profile.Global_Options = 0x71; if (card->d.features & DI_CODEC) a->profile.Global_Options |= 0x2; a->profile.B1_Protocols = 0x43; a->profile.B2_Protocols = 0x1f0f; a->profile.B3_Protocols = 0x07; a->manufacturer_features = 0; } a->li_pri = (a->profile.Channels > 2); a->li_channels = a->li_pri ? MIXER_CHANNELS_PRI : MIXER_CHANNELS_BRI; a->li_base = 0; for (i = 0; &adapter[i] != a; i++) { if (adapter[i].request) a->li_base = adapter[i].li_base + adapter[i].li_channels; } k = li_total_channels + a->li_channels; new_li_config_table = (LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3)); if (new_li_config_table == NULL) { DBG_ERR(("diva_add_card: failed alloc li_config table.")) memset(a, 0, sizeof(DIVA_CAPI_ADAPTER)); return (0); } /* Prevent access to line interconnect table in process update */ diva_os_enter_spin_lock(&api_lock, &old_irql, "add card"); j = 0; for (i = 0; i < k; i++) { if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) memset(&new_li_config_table[i], 0, sizeof(LI_CONFIG)); else memcpy(&new_li_config_table[i], &li_config_table[j], sizeof(LI_CONFIG)); new_li_config_table[i].flag_table = ((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i) * ((k + 3) & ~3)); new_li_config_table[i].coef_table = ((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i + 1) * ((k + 3) & ~3)); if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) { new_li_config_table[i].adapter = a; memset(&new_li_config_table[i].flag_table[0], 0, k); memset(&new_li_config_table[i].coef_table[0], 0, k); } else { if (a->li_base != 0) { memcpy(&new_li_config_table[i].flag_table[0], &li_config_table[j].flag_table[0], a->li_base); memcpy(&new_li_config_table[i].coef_table[0], &li_config_table[j].coef_table[0], a->li_base); } memset(&new_li_config_table[i].flag_table[a->li_base], 0, a->li_channels); memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels); if (a->li_base + a->li_channels < k) { memcpy(&new_li_config_table[i].flag_table[a->li_base + a->li_channels], &li_config_table[j].flag_table[a->li_base], k - (a->li_base + a->li_channels)); memcpy(&new_li_config_table[i].coef_table[a->li_base + a->li_channels], &li_config_table[j].coef_table[a->li_base], k - (a->li_base + a->li_channels)); } j++; } } li_total_channels = k; mem_to_free = li_config_table; li_config_table = new_li_config_table; for (i = card->Id; i < max_adapter; i++) { if (adapter[i].request) adapter[i].li_base += a->li_channels; } if (a == &adapter[max_adapter]) max_adapter++; list_add(&(card->list), &cards); AutomaticLaw(a); diva_os_leave_spin_lock(&api_lock, &old_irql, "add card"); if (mem_to_free) { diva_os_free (0, mem_to_free); } i = 0; while (i++ < 30) { if (a->automatic_law > 3) break; diva_os_sleep(10); } /* profile information */ PUT_WORD(&ctrl->profile.nbchannel, card->d.channels); ctrl->profile.goptions = a->profile.Global_Options; ctrl->profile.support1 = a->profile.B1_Protocols; ctrl->profile.support2 = a->profile.B2_Protocols; ctrl->profile.support3 = a->profile.B3_Protocols; /* manufacturer profile information */ ctrl->profile.manu[0] = a->man_profile.private_options; ctrl->profile.manu[1] = a->man_profile.rtp_primary_payloads; ctrl->profile.manu[2] = a->man_profile.rtp_additional_payloads; ctrl->profile.manu[3] = 0; ctrl->profile.manu[4] = 0; capi_ctr_ready(ctrl); DBG_TRC(("adapter added, max_adapter=%d", max_adapter)); return (1);}/* * register appl */static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params * rp){ APPL *this; word bnum, xnum; int i = 0; unsigned char *p; void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used; void **xbuffer_ptr, **xbuffer_internal; diva_os_spin_lock_magic_t old_irql; unsigned int mem_len; int nconn = rp->level3cnt; if (diva_os_in_irq()) { DBG_ERR(("CAPI_REGISTER - in irq context !")) return; } DBG_TRC(("application register Id=%d", appl)) if (appl > MAX_APPL) { DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL")) return; } if (nconn <= 0) nconn = ctrl->profile.nbchannel * -nconn; if (nconn == 0) nconn = ctrl->profile.nbchannel; DBG_LOG(("CAPI_REGISTER - Id = %d", appl)) DBG_LOG((" MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt)) DBG_LOG((" MaxBDataBuffers = %d", rp->datablkcnt)) DBG_LOG((" MaxBDataLength = %d", rp->datablklen)) if (nconn < 1 || nconn > 255 || rp->datablklen < 80 || rp->datablklen > 2150 || rp->datablkcnt > 255) { DBG_ERR(("CAPI_REGISTER - invalid parameters")) return; } if (application[appl - 1].Id == appl) { DBG_LOG(("CAPI_REGISTER - appl already registered")) return; /* appl already registered */ } /* alloc memory */ bnum = nconn * rp->datablkcnt; xnum = nconn * MAX_DATA_B3; mem_len = bnum * sizeof(word); /* DataNCCI */ mem_len += bnum * sizeof(word); /* DataFlags */ mem_len += bnum * rp->datablklen; /* ReceiveBuffer */ mem_len += xnum; /* xbuffer_used */ mem_len += xnum * sizeof(void *); /* xbuffer_ptr */ mem_len += xnum * sizeof(void *); /* xbuffer_internal */ mem_len += xnum * rp->datablklen; /* xbuffer_ptr[xnum] */ DBG_LOG((" Allocated Memory = %d", mem_len)) if (!(p = diva_os_malloc(0, mem_len))) { DBG_ERR(("CAPI_REGISTER - memory allocation failed")) return; } memset(p, 0, mem_len); DataNCCI = (void *)p; p += bnum * sizeof(word); DataFlags = (void *)p; p += bnum * sizeof(word); ReceiveBuffer = (void *)p; p += bnum * rp->datablklen; xbuffer_used = (void *)p; p += xnum; xbuffer_ptr = (void **)p; p += xnum * sizeof(void *); xbuffer_internal = (void **)p; p += xnum * sizeof(void *); for (i = 0; i < xnum; i++) { xbuffer_ptr[i] = (void *)p; p += rp->datablklen; } /* initialize application data */ diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl"); this = &application[appl - 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -