Merge branch 'capi' of ssh://git.misdn.eu/mISDNuser-devel into capi
This commit is contained in:
commit
ab44464d37
|
@ -175,6 +175,18 @@ void SendCmsgAnswer2Application(struct mApplication *appl, struct mc_buf *mc, __
|
||||||
SendCmsg2Application(appl, mc);
|
SendCmsg2Application(appl, mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lPLCI *get_lPLCI4plci(struct mApplication *appl, uint32_t id)
|
||||||
|
{
|
||||||
|
struct lController *lc;
|
||||||
|
struct mPLCI *plci;
|
||||||
|
|
||||||
|
lc = get_lController(appl, id & 0x7f);
|
||||||
|
if (!lc)
|
||||||
|
return NULL;
|
||||||
|
plci = getPLCI4Id(lc->Contr, id & 0xFFFF);
|
||||||
|
return get_lPLCI4Id(plci, appl->AppId);
|
||||||
|
}
|
||||||
|
|
||||||
#define CapiFacilityNotSupported 0x300b
|
#define CapiFacilityNotSupported 0x300b
|
||||||
|
|
||||||
static int FacilityMessage(struct mApplication *appl, struct pController *pc, struct mc_buf *mc)
|
static int FacilityMessage(struct mApplication *appl, struct pController *pc, struct mc_buf *mc)
|
||||||
|
|
244
capi20/daemon.c
244
capi20/daemon.c
|
@ -11,15 +11,16 @@
|
||||||
* this package for more details.
|
* this package for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <mISDN/q931.h>
|
#include <mISDN/q931.h>
|
||||||
|
#include <string.h>
|
||||||
#include "m_capi.h"
|
#include "m_capi.h"
|
||||||
#include "mc_buffer.h"
|
#include "mc_buffer.h"
|
||||||
#include "m_capi_sock.h"
|
#include "m_capi_sock.h"
|
||||||
|
@ -30,6 +31,14 @@
|
||||||
/* should be moved to capi_debug.h */
|
/* should be moved to capi_debug.h */
|
||||||
#include <capi_debug.h>
|
#include <capi_debug.h>
|
||||||
|
|
||||||
|
/* for some reasons when _XOPEN_SOURCE 600 was defined lot of other things are not longer
|
||||||
|
* defined so use this as workaround
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int grantpt(int fd);
|
||||||
|
extern int unlockpt(int fd);
|
||||||
|
extern int ptsname_r(int fd, char *buf, size_t buflen);
|
||||||
|
|
||||||
#ifndef DEF_CONFIG_FILE
|
#ifndef DEF_CONFIG_FILE
|
||||||
#define DEF_CONFIG_FILE "/etc/capi20.conf"
|
#define DEF_CONFIG_FILE "/etc/capi20.conf"
|
||||||
#endif
|
#endif
|
||||||
|
@ -369,38 +378,126 @@ struct BInstance *ControllerSelChannel(struct pController *pc, int nr, int proto
|
||||||
return bi;
|
return bi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int Create_tty(struct BInstance *bi)
|
||||||
|
{
|
||||||
|
int ret, pmod;
|
||||||
|
|
||||||
|
ret = posix_openpt(O_RDWR | O_NOCTTY);
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Cannot open terminal - %s\n", strerror(errno));
|
||||||
|
} else {
|
||||||
|
bi->tty = ret;
|
||||||
|
ret = grantpt(bi->tty);
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Error on grantpt - %s\n", strerror(errno));
|
||||||
|
close(bi->tty);
|
||||||
|
bi->tty = -1;
|
||||||
|
} else {
|
||||||
|
ret = unlockpt(bi->tty);
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Error on unlockpt - %s\n", strerror(errno));
|
||||||
|
close(bi->tty);
|
||||||
|
bi->tty = -1;
|
||||||
|
} else {
|
||||||
|
/* packet mode */
|
||||||
|
pmod = 1;
|
||||||
|
ret = ioctl(bi->tty, TIOCPKT, &pmod);
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Cannot set packet mode - %s\n", strerror(errno));
|
||||||
|
close(bi->tty);
|
||||||
|
bi->tty = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int recvBchannel(struct BInstance *);
|
static int recvBchannel(struct BInstance *);
|
||||||
|
|
||||||
|
|
||||||
|
static int recv_tty(struct BInstance *bi)
|
||||||
|
{
|
||||||
|
int ret, maxl;
|
||||||
|
struct mc_buf *mc;
|
||||||
|
|
||||||
|
mc = alloc_mc_buf();
|
||||||
|
if (!mc)
|
||||||
|
return -ENOMEM;
|
||||||
|
if (!bi)
|
||||||
|
return -EINVAL;
|
||||||
|
mc->rp = mc->rb + 8;
|
||||||
|
maxl = MC_RB_SIZE - 8;
|
||||||
|
ret = read(bi->tty, mc->rp, maxl);
|
||||||
|
if (ret < 0) {
|
||||||
|
wprint("Error on reading from tty %d errno %d - %s\n", bi->tty, errno, strerror(errno));
|
||||||
|
ret = -errno;
|
||||||
|
} else if (ret == 0) {
|
||||||
|
/* closed */
|
||||||
|
wprint("Read 0 bytes from tty %d\n", bi->tty);
|
||||||
|
ret = -ECONNABORTED;
|
||||||
|
} else if (ret == maxl) {
|
||||||
|
eprint("Message too big %d ctrl %02x (%02x%02x%02x%02x%02x%02x%02x%02x)\n",
|
||||||
|
ret, mc->rp[0], mc->rp[1], mc->rp[2], mc->rp[3], mc->rp[4], mc->rp[5], mc->rp[6], mc->rp[7], mc->rp[8]);
|
||||||
|
ret = -EMSGSIZE;
|
||||||
|
}
|
||||||
|
if (ret > 0) {
|
||||||
|
mc->len = ret;
|
||||||
|
/* Fake length of DATA_B3 REQ to pass offset check */
|
||||||
|
capimsg_setu16(mc->rb, 0, 22);
|
||||||
|
mc->cmsg.Command = CAPI_DATA_TTY;
|
||||||
|
mc->cmsg.Subcommand = CAPI_REQ;
|
||||||
|
ret = bi->from_up(bi, mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0) /* if message is not queued or freed */
|
||||||
|
free_mc_buf(mc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void *BCthread(void *arg)
|
static void *BCthread(void *arg)
|
||||||
{
|
{
|
||||||
struct BInstance *bi = arg;
|
struct BInstance *bi = arg;
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
bi->running = 1;
|
bi->running = 1;
|
||||||
while (bi->running) {
|
while (bi->running) {
|
||||||
ret = poll(bi->pfd, 2, -1);
|
ret = poll(bi->pfd, bi->pcnt, -1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
wprint("Bchannel%d Error on poll - %s\n", bi->nr, strerror(errno));
|
wprint("Bchannel%d Error on poll - %s\n", bi->nr, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
for (i = 1; i < bi->pcnt; i++) {
|
||||||
|
if (bi->pfd[i].revents & POLLIN) {
|
||||||
|
switch(i) {
|
||||||
|
case 1:
|
||||||
|
ret = recvBchannel(bi);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ret = recv_tty(bi);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wprint("Bchannel%d poll idx %d not handled\n", bi->nr, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bi->pfd[0].revents & POLLIN) {
|
if (bi->pfd[0].revents & POLLIN) {
|
||||||
ret = recvBchannel(bi);
|
ret = read(bi->pfd[0].fd, &cmd, 1);
|
||||||
} else if (bi->pfd[1].revents & POLLIN) {
|
|
||||||
ret = read(bi->pfd[1].fd, &cmd, 1);
|
|
||||||
if (cmd == 42) {
|
if (cmd == 42) {
|
||||||
bi->running = 0;
|
bi->running = 0;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
wprint("Bchannel%d no POLLIN event\n", bi->nr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CreateBchannelThread(struct BInstance *bi)
|
static int CreateBchannelThread(struct BInstance *bi, int pcnt)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
ret = pipe(bi->cpipe);
|
ret = pipe(bi->cpipe);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -417,10 +514,11 @@ static int CreateBchannelThread(struct BInstance *bi)
|
||||||
eprint("error - %s\n", strerror(errno));
|
eprint("error - %s\n", strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
bi->pfd[0].fd = bi->fd;
|
bi->pfd[0].fd = bi->cpipe[0];
|
||||||
bi->pfd[0].events = POLLIN | POLLPRI;
|
bi->pfd[0].events = POLLIN | POLLPRI;
|
||||||
bi->pfd[1].fd = bi->cpipe[0];
|
bi->pfd[1].fd = bi->fd;
|
||||||
bi->pfd[1].events = POLLIN | POLLPRI;
|
bi->pfd[1].events = POLLIN | POLLPRI;
|
||||||
|
bi->pcnt = pcnt;
|
||||||
ret = pthread_create(&bi->tid, NULL, BCthread, bi);
|
ret = pthread_create(&bi->tid, NULL, BCthread, bi);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
eprint("Cannot create thread error - %s\n", strerror(errno));
|
eprint("Cannot create thread error - %s\n", strerror(errno));
|
||||||
|
@ -429,7 +527,8 @@ static int CreateBchannelThread(struct BInstance *bi)
|
||||||
bi->cpipe[0] = -1;
|
bi->cpipe[0] = -1;
|
||||||
bi->cpipe[1] = -1;
|
bi->cpipe[1] = -1;
|
||||||
bi->pfd[0].fd = -1;
|
bi->pfd[0].fd = -1;
|
||||||
bi->pfd[1].fd = -1;
|
for (i = 1; i < bi->pcnt; i++)
|
||||||
|
bi->pfd[i].fd = -1;
|
||||||
} else
|
} else
|
||||||
iprint("Created Bchannel tread %d\n", (int)bi->tid);
|
iprint("Created Bchannel tread %d\n", (int)bi->tid);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -437,7 +536,7 @@ static int CreateBchannelThread(struct BInstance *bi)
|
||||||
|
|
||||||
static int StopBchannelThread(struct BInstance *bi)
|
static int StopBchannelThread(struct BInstance *bi)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
|
|
||||||
if (bi->running) {
|
if (bi->running) {
|
||||||
|
@ -453,7 +552,9 @@ static int StopBchannelThread(struct BInstance *bi)
|
||||||
close(bi->cpipe[0]);
|
close(bi->cpipe[0]);
|
||||||
close(bi->cpipe[1]);
|
close(bi->cpipe[1]);
|
||||||
bi->pfd[0].fd = -1;
|
bi->pfd[0].fd = -1;
|
||||||
bi->pfd[1].fd = -1;
|
for (i = 1; i < bi->pcnt; i++)
|
||||||
|
bi->pfd[i].fd = -1;
|
||||||
|
bi->pcnt = 0;
|
||||||
bi->cpipe[0] = -1;
|
bi->cpipe[0] = -1;
|
||||||
bi->cpipe[1] = -1;
|
bi->cpipe[1] = -1;
|
||||||
}
|
}
|
||||||
|
@ -496,11 +597,15 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp, enum BType btype)
|
||||||
bi->from_up = ncciB3Data;
|
bi->from_up = ncciB3Data;
|
||||||
break;
|
break;
|
||||||
#ifdef USE_SOFTFAX
|
#ifdef USE_SOFTFAX
|
||||||
case BType_Fax:
|
case BType_Fax:
|
||||||
bi->from_down = FaxRecvBData;
|
bi->from_down = FaxRecvBData;
|
||||||
bi->from_up = FaxB3Message;
|
bi->from_up = FaxB3Message;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case BType_tty:
|
||||||
|
bi->from_down = recvBdirect;
|
||||||
|
bi->from_up = ncciB3Data;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
eprint("Error unnkown BType %d\n", btype);
|
eprint("Error unnkown BType %d\n", btype);
|
||||||
close(sk);
|
close(sk);
|
||||||
|
@ -538,10 +643,33 @@ int OpenBInstance(struct BInstance *bi, struct lPLCI *lp, enum BType btype)
|
||||||
bi->UpId = 0;
|
bi->UpId = 0;
|
||||||
bi->DownId = 0;
|
bi->DownId = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (btype == BType_Fax) {
|
||||||
ret = CreateBchannelThread(bi);
|
ret = CreateBchannelThread(bi, 2);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
eprint("Error while creating B-channel thread)\n");
|
eprint("Error while creating B%d-channel thread\n", bi->nr);
|
||||||
|
close(sk);
|
||||||
|
bi->fd = -1;
|
||||||
|
bi->lp = NULL;
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
bi->UpId = 0;
|
||||||
|
bi->DownId = 0;
|
||||||
|
}
|
||||||
|
} else if (btype == BType_tty) {
|
||||||
|
ret = Create_tty(bi);
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Error while creating B%d-channel tty\n", bi->nr);
|
||||||
|
close(sk);
|
||||||
|
bi->fd = -1;
|
||||||
|
bi->lp = NULL;
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
bi->pfd[2].fd = bi->tty;
|
||||||
|
bi->pfd[2].events = POLLIN | POLLPRI;
|
||||||
|
ret = CreateBchannelThread(bi, 3);
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
eprint("Error while creating B%d-channel thread\n", bi->nr);
|
||||||
close(sk);
|
close(sk);
|
||||||
bi->fd = -1;
|
bi->fd = -1;
|
||||||
bi->lp = NULL;
|
bi->lp = NULL;
|
||||||
|
@ -570,6 +698,11 @@ int CloseBInstance(struct BInstance *bi)
|
||||||
StopBchannelThread(bi);
|
StopBchannelThread(bi);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case BType_tty:
|
||||||
|
StopBchannelThread(bi);
|
||||||
|
if (bi->tty > -1)
|
||||||
|
close(bi->tty);
|
||||||
|
bi->tty = -1;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -915,6 +1048,70 @@ static void misdn_manufacturer_req(int fd, struct mc_buf *mc)
|
||||||
eprint("error send %d/%d - %s\n", ret, 10, strerror(errno));
|
eprint("error send %d/%d - %s\n", ret, 10, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mIcapi_userflag(int fd, int idx, struct mc_buf *mc)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct mApplication *appl = pollinfo[idx].data;
|
||||||
|
uint32_t sf, cf, uf = 0xffffffff;
|
||||||
|
|
||||||
|
CAPIMSG_SETSUBCOMMAND(mc->rb, CAPI_CONF);
|
||||||
|
capimsg_setu16(mc->rb, 0, 12);
|
||||||
|
if (appl) {
|
||||||
|
uf = appl->UserFlags;
|
||||||
|
sf = CAPIMSG_U32(mc->rb, 8);
|
||||||
|
cf = CAPIMSG_U32(mc->rb, 12);
|
||||||
|
if (cf)
|
||||||
|
uf &= ~cf;
|
||||||
|
if (sf)
|
||||||
|
uf |= sf;
|
||||||
|
iprint("UserFlags old=%x new=%x\n", appl->UserFlags, uf);
|
||||||
|
appl->UserFlags = uf;
|
||||||
|
}
|
||||||
|
capimsg_setu32(mc->rb, 8, uf);
|
||||||
|
ret = send(fd, mc->rb, 12, 0);
|
||||||
|
if (ret != 12)
|
||||||
|
eprint("error send %d/%d - %s\n", ret, 12, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mIcapi_ttyname(int fd, int idx, struct mc_buf *mc)
|
||||||
|
{
|
||||||
|
int ret, ml, l = 0;
|
||||||
|
struct mApplication *appl = pollinfo[idx].data;
|
||||||
|
struct lPLCI *lp;
|
||||||
|
uint32_t ncci = 0;
|
||||||
|
char name[80];
|
||||||
|
|
||||||
|
CAPIMSG_SETSUBCOMMAND(mc->rb, CAPI_CONF);
|
||||||
|
if (appl) {
|
||||||
|
ncci = CAPIMSG_U32(mc->rb, 8);
|
||||||
|
ml = CAPIMSG_U32(mc->rb, 12);
|
||||||
|
if (appl->UserFlags & CAPIFLAG_HIGHJACKING) {
|
||||||
|
lp = get_lPLCI4plci(appl, ncci);
|
||||||
|
if (lp->BIlink && lp->BIlink->tty > -1) {
|
||||||
|
ret = ptsname_r(lp->BIlink->tty, name, 80);
|
||||||
|
if (ret)
|
||||||
|
eprint("NCCI %06x: error to get ptsname for %d - %s\n",
|
||||||
|
ncci, lp->BIlink->tty, strerror(errno));
|
||||||
|
else
|
||||||
|
l = strlen(name);
|
||||||
|
} else
|
||||||
|
eprint("NCCI %06x: do not find lPLCI for NCCI\n", ncci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (l >= ml)
|
||||||
|
l = 0;
|
||||||
|
if (l) {
|
||||||
|
iprint("NCCI %06x: ttyname set to %s\n", ncci, name);
|
||||||
|
memcpy(&mc->rb[8], name, l);
|
||||||
|
} else
|
||||||
|
wprint("NCCI %06x: ttyname requested but not available\n", ncci);
|
||||||
|
mc->rb[8 + l] = 0;
|
||||||
|
capimsg_setu16(mc->rb, 0, l + 8);
|
||||||
|
ret = send(fd, mc->rb, l + 8, 0);
|
||||||
|
if (ret != l + 8)
|
||||||
|
eprint("error send %d/%d - %s\n", ret, 12, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
static int main_recv(int fd, int idx)
|
static int main_recv(int fd, int idx)
|
||||||
{
|
{
|
||||||
int ret, len, cmd, dl;
|
int ret, len, cmd, dl;
|
||||||
|
@ -980,6 +1177,12 @@ static int main_recv(int fd, int idx)
|
||||||
case MIC_MANUFACTURER_REQ:
|
case MIC_MANUFACTURER_REQ:
|
||||||
misdn_manufacturer_req(fd, mc);
|
misdn_manufacturer_req(fd, mc);
|
||||||
break;
|
break;
|
||||||
|
case MIC_USERFLAG_REQ:
|
||||||
|
mIcapi_userflag(fd, idx, mc);
|
||||||
|
break;
|
||||||
|
case MIC_TTYNAME_REQ:
|
||||||
|
mIcapi_ttyname(fd, idx, mc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (pollinfo[idx].type == PIT_Application)
|
if (pollinfo[idx].type == PIT_Application)
|
||||||
ret = PutMessageApplication(pollinfo[idx].data, mc);
|
ret = PutMessageApplication(pollinfo[idx].data, mc);
|
||||||
|
@ -1236,6 +1439,7 @@ int main(int argc, char *argv[])
|
||||||
pc->BInstances[j].nr = j;
|
pc->BInstances[j].nr = j;
|
||||||
pc->BInstances[j].pc = pc;
|
pc->BInstances[j].pc = pc;
|
||||||
pc->BInstances[j].fd = -1;
|
pc->BInstances[j].fd = -1;
|
||||||
|
pc->BInstances[j].tty = -1;
|
||||||
sem_init(&pc->BInstances[j].wait, 0, 0);
|
sem_init(&pc->BInstances[j].wait, 0, 0);
|
||||||
}
|
}
|
||||||
pc->profile.ncontroller = i + 1;
|
pc->profile.ncontroller = i + 1;
|
||||||
|
|
|
@ -1642,6 +1642,7 @@ static int lPLCILinkUp(struct lPLCI *lp)
|
||||||
int proto = -1, ret = 0, act_l1;
|
int proto = -1, ret = 0, act_l1;
|
||||||
struct mISDNhead mh;
|
struct mISDNhead mh;
|
||||||
enum BType btype = BType_None;
|
enum BType btype = BType_None;
|
||||||
|
struct mApplication *ap = lp->lc->Appl;
|
||||||
|
|
||||||
mh.id = 1;
|
mh.id = 1;
|
||||||
mh.prim = 0;
|
mh.prim = 0;
|
||||||
|
@ -1716,6 +1717,9 @@ static int lPLCILinkUp(struct lPLCI *lp)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (ap->UserFlags & CAPIFLAG_HIGHJACKING) {
|
||||||
|
btype = BType_tty;
|
||||||
|
}
|
||||||
dprint(MIDEBUG_PLCI, "lPLCILinkUp B1(%x) B2(%x) B3(%x) ch(%d) proto(%x)\n",
|
dprint(MIDEBUG_PLCI, "lPLCILinkUp B1(%x) B2(%x) B3(%x) ch(%d) proto(%x)\n",
|
||||||
lp->Bprotocol.B1, lp->Bprotocol.B2, lp->Bprotocol.B3, lp->chid.nr, proto);
|
lp->Bprotocol.B1, lp->Bprotocol.B2, lp->Bprotocol.B3, lp->chid.nr, proto);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,8 @@ typedef int (BDataTrans_t)(struct BInstance *, struct mc_buf *);
|
||||||
enum BType {
|
enum BType {
|
||||||
BType_None = 0,
|
BType_None = 0,
|
||||||
BType_Direct = 1,
|
BType_Direct = 1,
|
||||||
BType_Fax = 2
|
BType_Fax = 2,
|
||||||
|
BType_tty = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BInstance {
|
struct BInstance {
|
||||||
|
@ -69,6 +70,7 @@ struct BInstance {
|
||||||
int usecnt;
|
int usecnt;
|
||||||
int proto;
|
int proto;
|
||||||
int fd;
|
int fd;
|
||||||
|
int tty;
|
||||||
enum BType type;
|
enum BType type;
|
||||||
uint16_t DownId; /* Ids for send down messages */
|
uint16_t DownId; /* Ids for send down messages */
|
||||||
uint16_t UpId; /* Ids for send up messages */
|
uint16_t UpId; /* Ids for send up messages */
|
||||||
|
@ -78,7 +80,8 @@ struct BInstance {
|
||||||
BDataTrans_t *from_down;
|
BDataTrans_t *from_down;
|
||||||
BDataTrans_t *from_up;
|
BDataTrans_t *from_up;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
struct pollfd pfd[2];
|
struct pollfd pfd[4];
|
||||||
|
int pcnt;
|
||||||
int cpipe[2];
|
int cpipe[2];
|
||||||
sem_t wait;
|
sem_t wait;
|
||||||
unsigned int running:1;
|
unsigned int running:1;
|
||||||
|
@ -154,6 +157,7 @@ struct mApplication {
|
||||||
int MaxB3Con;
|
int MaxB3Con;
|
||||||
int MaxB3Blk;
|
int MaxB3Blk;
|
||||||
int MaxB3Size;
|
int MaxB3Size;
|
||||||
|
uint32_t UserFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mApplication *RegisterApplication(uint16_t, uint32_t, uint32_t, uint32_t);
|
struct mApplication *RegisterApplication(uint16_t, uint32_t, uint32_t, uint32_t);
|
||||||
|
@ -217,6 +221,7 @@ struct mNCCI *getNCCI4addr(struct lPLCI *, uint32_t, int);
|
||||||
void lPLCIDelNCCI(struct mNCCI *);
|
void lPLCIDelNCCI(struct mNCCI *);
|
||||||
struct mNCCI *ConnectB3Request(struct lPLCI *, struct mc_buf *);
|
struct mNCCI *ConnectB3Request(struct lPLCI *, struct mc_buf *);
|
||||||
void B3ReleaseLink(struct lPLCI *, struct BInstance *);
|
void B3ReleaseLink(struct lPLCI *, struct BInstance *);
|
||||||
|
struct lPLCI *get_lPLCI4plci(struct mApplication *, uint32_t);
|
||||||
|
|
||||||
#define GET_NCCI_EXACT 1
|
#define GET_NCCI_EXACT 1
|
||||||
#define GET_NCCI_ONLY_PLCI 2
|
#define GET_NCCI_ONLY_PLCI 2
|
||||||
|
@ -265,6 +270,7 @@ struct mNCCI {
|
||||||
unsigned char up_header[30];
|
unsigned char up_header[30];
|
||||||
unsigned int dtmflisten:1;
|
unsigned int dtmflisten:1;
|
||||||
unsigned int l1direct:1;
|
unsigned int l1direct:1;
|
||||||
|
unsigned int l1trans:1;
|
||||||
unsigned int l2trans:1;
|
unsigned int l2trans:1;
|
||||||
unsigned int l3trans:1;
|
unsigned int l3trans:1;
|
||||||
unsigned int dlbusy:1;
|
unsigned int dlbusy:1;
|
||||||
|
@ -362,6 +368,11 @@ void mCapi_message2str(struct mc_buf *);
|
||||||
|
|
||||||
#define CAPI_B3_DATA_IND_HEADER_SIZE ((4 == sizeof(void *)) ? 22 : 30)
|
#define CAPI_B3_DATA_IND_HEADER_SIZE ((4 == sizeof(void *)) ? 22 : 30)
|
||||||
|
|
||||||
|
|
||||||
|
#define CAPIFLAG_HIGHJACKING 1
|
||||||
|
|
||||||
|
#define CAPI_DATA_TTY 0xe0
|
||||||
|
|
||||||
/* some helper */
|
/* some helper */
|
||||||
static inline int capiEncodeWord(unsigned char *p, uint16_t i)
|
static inline int capiEncodeWord(unsigned char *p, uint16_t i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,8 @@ extern "C" {
|
||||||
#define MIC_VERSION_REQ CAPICMD(0xf4, 0xff)
|
#define MIC_VERSION_REQ CAPICMD(0xf4, 0xff)
|
||||||
#define MIC_GET_MANUFACTURER_REQ CAPICMD(0xf5, 0xff)
|
#define MIC_GET_MANUFACTURER_REQ CAPICMD(0xf5, 0xff)
|
||||||
#define MIC_MANUFACTURER_REQ CAPICMD(0xf6, 0xff)
|
#define MIC_MANUFACTURER_REQ CAPICMD(0xf6, 0xff)
|
||||||
|
#define MIC_USERFLAG_REQ CAPICMD(0xf7, 0xff)
|
||||||
|
#define MIC_TTYNAME_REQ CAPICMD(0xf8, 0xff)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -422,6 +422,87 @@ static unsigned misdnGetProfile(int nHandle, unsigned nController, unsigned char
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int misdnFlagReq(uint16_t ApplId, uint32_t set_f, uint32_t clr_f)
|
||||||
|
{
|
||||||
|
unsigned char anBuf[100];
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = capi_applid2fd(ApplId);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
misdnSetHeader(anBuf, 16, ApplId, MIC_USERFLAG_REQ, 0);
|
||||||
|
capimsg_setu32(anBuf, 8, set_f);
|
||||||
|
capimsg_setu32(anBuf, 12, clr_f);
|
||||||
|
ret = misdnRemoteCommand(fd, anBuf, 16, MIC_USERFLAG_REQ);
|
||||||
|
if (ret == 12)
|
||||||
|
ret = CAPIMSG_U32(anBuf, 8);
|
||||||
|
else
|
||||||
|
ret = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int misdnGetFlags(unsigned nApplId, unsigned *pnFlagsPtr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = misdnFlagReq(nApplId, 0, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
*pnFlagsPtr = 0;
|
||||||
|
else {
|
||||||
|
*pnFlagsPtr = ret;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int misdnSetFlags(unsigned nApplId, unsigned nFlags)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = misdnFlagReq(nApplId, nFlags, 0);
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int misdnClearFlags(unsigned nApplId, unsigned nFlags)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = misdnFlagReq(nApplId, 0, nFlags);
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *misdnGetTtyDeviceName(unsigned nApplId,unsigned nNcci, char *pnBuffer, size_t nSize)
|
||||||
|
{
|
||||||
|
unsigned char *anBuf;
|
||||||
|
int ret, fd;
|
||||||
|
|
||||||
|
fd = capi_applid2fd(nApplId);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (nSize > 64)
|
||||||
|
nSize = 64;
|
||||||
|
anBuf = malloc(nSize + 12);
|
||||||
|
if (!anBuf)
|
||||||
|
return NULL;
|
||||||
|
misdnSetHeader(anBuf, 16, nApplId, MIC_TTYNAME_REQ, 0);
|
||||||
|
capimsg_setu32(anBuf, 8, nNcci);
|
||||||
|
capimsg_setu32(anBuf, 12, nSize & 0xff);
|
||||||
|
ret = misdnRemoteCommand(fd, anBuf, 16, MIC_TTYNAME_REQ);
|
||||||
|
if (ret > 8) {
|
||||||
|
ret = ret - 8;
|
||||||
|
memcpy(pnBuffer, &anBuf[8], ret);
|
||||||
|
pnBuffer[ret] = 0;
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
free(anBuf);
|
||||||
|
return pnBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
/** Module operations structure */
|
/** Module operations structure */
|
||||||
static struct sModuleOperations sRemoteCapi = {
|
static struct sModuleOperations sRemoteCapi = {
|
||||||
misdnIsInstalled,
|
misdnIsInstalled,
|
||||||
|
@ -434,10 +515,10 @@ static struct sModuleOperations sRemoteCapi = {
|
||||||
misdnGetSerialNumber,
|
misdnGetSerialNumber,
|
||||||
misdnGetProfile,
|
misdnGetProfile,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
misdnGetFlags,
|
||||||
NULL,
|
misdnSetFlags,
|
||||||
NULL,
|
misdnClearFlags,
|
||||||
NULL,
|
misdnGetTtyDeviceName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
122
capi20/ncci.c
122
capi20/ncci.c
|
@ -378,7 +378,7 @@ static void ncci_n0_dl_establish_ind_conf(struct FsmInst *fi, int event, void *a
|
||||||
FsmEvent(&ncci->ncci_m, EV_NC_CONNECT_B3_IND, arg);
|
FsmEvent(&ncci->ncci_m, EV_NC_CONNECT_B3_IND, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ncci_dl_establish_conf(struct FsmInst *fi, int event, void *arg)
|
static void ncci_dl_establish_ind_conf(struct FsmInst *fi, int event, void *arg)
|
||||||
{
|
{
|
||||||
struct mNCCI *ncci = fi->userdata;
|
struct mNCCI *ncci = fi->userdata;
|
||||||
struct mc_buf *mc = arg;
|
struct mc_buf *mc = arg;
|
||||||
|
@ -453,7 +453,8 @@ static struct FsmNode fn_ncci_list[] = {
|
||||||
{ST_NCCI_N_2, EV_AP_DISCONNECT_B3_REQ, ncci_disconnect_b3_req},
|
{ST_NCCI_N_2, EV_AP_DISCONNECT_B3_REQ, ncci_disconnect_b3_req},
|
||||||
{ST_NCCI_N_2, EV_NC_DISCONNECT_B3_IND, ncci_disconnect_b3_ind},
|
{ST_NCCI_N_2, EV_NC_DISCONNECT_B3_IND, ncci_disconnect_b3_ind},
|
||||||
{ST_NCCI_N_2, EV_NC_DISCONNECT_B3_CONF, ncci_disconnect_b3_conf},
|
{ST_NCCI_N_2, EV_NC_DISCONNECT_B3_CONF, ncci_disconnect_b3_conf},
|
||||||
{ST_NCCI_N_2, EV_DL_ESTABLISH_CONF, ncci_dl_establish_conf},
|
{ST_NCCI_N_2, EV_DL_ESTABLISH_CONF, ncci_dl_establish_ind_conf},
|
||||||
|
{ST_NCCI_N_2, EV_DL_ESTABLISH_IND, ncci_dl_establish_ind_conf},
|
||||||
{ST_NCCI_N_2, EV_DL_RELEASE_IND, ncci_dl_release_ind_conf},
|
{ST_NCCI_N_2, EV_DL_RELEASE_IND, ncci_dl_release_ind_conf},
|
||||||
{ST_NCCI_N_2, EV_AP_MANUFACTURER_REQ, ncci_manufacturer_req},
|
{ST_NCCI_N_2, EV_AP_MANUFACTURER_REQ, ncci_manufacturer_req},
|
||||||
{ST_NCCI_N_2, EV_AP_RELEASE, ncci_appl_release_disc},
|
{ST_NCCI_N_2, EV_AP_RELEASE, ncci_appl_release_disc},
|
||||||
|
@ -551,7 +552,11 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
||||||
nc->window = lp->lc->Appl->MaxB3Blk;
|
nc->window = lp->lc->Appl->MaxB3Blk;
|
||||||
pthread_mutex_init(&nc->lock, NULL);
|
pthread_mutex_init(&nc->lock, NULL);
|
||||||
switch (lp->Bprotocol.B1) {
|
switch (lp->Bprotocol.B1) {
|
||||||
|
case 0:
|
||||||
|
nc->l1trans = 0;
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
nc->l1trans = 1;
|
||||||
if (!lp->l1dtmf) {
|
if (!lp->l1dtmf) {
|
||||||
nc->flowmode = flmPHDATA;
|
nc->flowmode = flmPHDATA;
|
||||||
nc->l1direct = 1;
|
nc->l1direct = 1;
|
||||||
|
@ -567,12 +572,18 @@ struct mNCCI *ncciCreate(struct lPLCI *lp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp->Bprotocol.B2 == 0) { /* X.75 has own flowctrl */
|
if (lp->Bprotocol.B2 == 1) { /* X.75 has own flowctrl */
|
||||||
nc->l2trans = 1;
|
nc->l2trans = 1;
|
||||||
if (lp->Bprotocol.B1 == 0) {
|
if (lp->Bprotocol.B1 == 0) {
|
||||||
nc->l1direct = 1;
|
nc->l1direct = 1;
|
||||||
nc->flowmode = flmPHDATA;
|
nc->flowmode = flmPHDATA;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nc->l2trans = 1;
|
||||||
|
if (lp->Bprotocol.B1 == 0) { // HDLC
|
||||||
|
nc->l1direct = 1;
|
||||||
|
nc->flowmode = flmPHDATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lp->Bprotocol.B3 == 0) {
|
if (lp->Bprotocol.B3 == 0) {
|
||||||
nc->l3trans = 1;
|
nc->l3trans = 1;
|
||||||
|
@ -788,19 +799,44 @@ static uint16_t ncciDataReq(struct mNCCI *ncci, struct mc_buf *mc)
|
||||||
AnswerDataB3Req(ncci, mc, CapiMessageNotSupportedInCurrentState);
|
AnswerDataB3Req(ncci, mc, CapiMessageNotSupportedInCurrentState);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ncci->xmit_handles[ncci->iidx].pkt) {
|
if (ncci->BIlink->tty > -1) {
|
||||||
|
/* We have a packet from pseudo tty */
|
||||||
|
if (ncci->xmit_handles[ncci->iidx].pkt) {
|
||||||
|
wprint("NCCI %06x: tty CapiSendQueueFull\n", ncci->ncci);
|
||||||
|
/* TODO FLOW CONTROL */
|
||||||
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
|
free_mc_buf(mc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
len = mc->len;
|
||||||
|
if (*mc->rp == 0) {
|
||||||
|
len--;
|
||||||
|
mc->rp++;
|
||||||
|
dhexprint(MIDEBUG_NCCI_DATA, "Queued Data: ", mc->rp, len);
|
||||||
|
} else {
|
||||||
|
/* TODO FLOW CONTROL */
|
||||||
|
wprint("NCCI %06x: tty got ctrl %02x\n", ncci->ncci, *mc->rp);
|
||||||
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
|
free_mc_buf(mc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ncci->xmit_handles[ncci->iidx].DataHandle = 0;
|
||||||
|
ncci->xmit_handles[ncci->iidx].MsgId = 0;
|
||||||
|
off = 8;
|
||||||
|
} else if (ncci->xmit_handles[ncci->iidx].pkt) {
|
||||||
wprint("NCCI %06x: CapiSendQueueFull\n", ncci->ncci);
|
wprint("NCCI %06x: CapiSendQueueFull\n", ncci->ncci);
|
||||||
pthread_mutex_unlock(&ncci->lock);
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
AnswerDataB3Req(ncci, mc, CapiSendQueueFull);
|
AnswerDataB3Req(ncci, mc, CapiSendQueueFull);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
len = CAPIMSG_DATALEN(mc->rb);
|
||||||
|
ncci->xmit_handles[ncci->iidx].DataHandle = CAPIMSG_REQ_DATAHANDLE(mc->rb);
|
||||||
|
ncci->xmit_handles[ncci->iidx].MsgId = CAPIMSG_MSGID(mc->rb);
|
||||||
|
mc->rp = mc->rb + off;
|
||||||
}
|
}
|
||||||
len = CAPIMSG_DATALEN(mc->rb);
|
|
||||||
ncci->xmit_handles[ncci->iidx].pkt = mc;
|
ncci->xmit_handles[ncci->iidx].pkt = mc;
|
||||||
ncci->xmit_handles[ncci->iidx].DataHandle = CAPIMSG_REQ_DATAHANDLE(mc->rb);
|
|
||||||
ncci->xmit_handles[ncci->iidx].MsgId = CAPIMSG_MSGID(mc->rb);
|
|
||||||
ncci->xmit_handles[ncci->iidx].dlen = len;
|
ncci->xmit_handles[ncci->iidx].dlen = len;
|
||||||
ncci->xmit_handles[ncci->iidx].sent = 0;
|
ncci->xmit_handles[ncci->iidx].sent = 0;
|
||||||
mc->rp = mc->rb + off;
|
|
||||||
mc->len = len;
|
mc->len = len;
|
||||||
ncci->xmit_handles[ncci->iidx].sp = mc->rp;
|
ncci->xmit_handles[ncci->iidx].sp = mc->rp;
|
||||||
|
|
||||||
|
@ -838,6 +874,23 @@ static int ncciDataInd(struct mNCCI *ncci, int pr, struct mc_buf *mc)
|
||||||
wprint("NCCI %06x: : frame with %d bytes dropped BIlink gone\n", ncci->ncci, dlen);
|
wprint("NCCI %06x: : frame with %d bytes dropped BIlink gone\n", ncci->ncci, dlen);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
if (ncci->BIlink->tty > -1) {
|
||||||
|
/* transfer via a pseudo tty */
|
||||||
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
|
hh++;
|
||||||
|
mc->rp = (unsigned char *)hh;
|
||||||
|
ret = write(ncci->BIlink->tty, mc->rp, dlen);
|
||||||
|
if (ret != dlen)
|
||||||
|
wprint("NCCI %06x: frame with %d bytes only %d bytes were written to tty - %s\n",
|
||||||
|
ncci->ncci, dlen, ret, strerror(errno));
|
||||||
|
else {
|
||||||
|
dprint(MIDEBUG_NCCI, "NCCI %06x: frame with %d bytes was written to tty\n",
|
||||||
|
ncci->ncci, dlen);
|
||||||
|
dhexprint(MIDEBUG_NCCI_DATA, "Data: ", mc->rp, dlen);
|
||||||
|
}
|
||||||
|
free_mc_buf(mc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
for (i = 0; i < ncci->window; i++) {
|
for (i = 0; i < ncci->window; i++) {
|
||||||
if (ncci->recv_handles[i] == 0)
|
if (ncci->recv_handles[i] == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -871,7 +924,7 @@ static int ncciDataInd(struct mNCCI *ncci, int pr, struct mc_buf *mc)
|
||||||
|
|
||||||
pthread_mutex_unlock(&ncci->lock);
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
if (ret != tot) {
|
if (ret != tot) {
|
||||||
wprint("NCCI %06x: : frame with %d + %d bytes only %d bytes are sent - %s\n",
|
wprint("NCCI %06x: frame with %d + %d bytes only %d bytes are sent - %s\n",
|
||||||
ncci->ncci, dlen, CAPI_B3_DATA_IND_HEADER_SIZE, ret, strerror(errno));
|
ncci->ncci, dlen, CAPI_B3_DATA_IND_HEADER_SIZE, ret, strerror(errno));
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
} else
|
} else
|
||||||
|
@ -884,7 +937,7 @@ static int ncciDataInd(struct mNCCI *ncci, int pr, struct mc_buf *mc)
|
||||||
|
|
||||||
static void ncciDataConf(struct mNCCI *ncci, struct mc_buf *mc)
|
static void ncciDataConf(struct mNCCI *ncci, struct mc_buf *mc)
|
||||||
{
|
{
|
||||||
int i;
|
int i, do_answer = 1;
|
||||||
struct mISDNhead *hh;
|
struct mISDNhead *hh;
|
||||||
|
|
||||||
hh = (struct mISDNhead *)mc->rb;
|
hh = (struct mISDNhead *)mc->rb;
|
||||||
|
@ -895,6 +948,14 @@ static void ncciDataConf(struct mNCCI *ncci, struct mc_buf *mc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&ncci->lock);
|
pthread_mutex_lock(&ncci->lock);
|
||||||
|
if (!ncci->BIlink) {
|
||||||
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
|
wprint("NCCI %06x: ack dropped BIlink gone\n", ncci->ncci);
|
||||||
|
free_mc_buf(mc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ncci->BIlink->tty > -1)
|
||||||
|
do_answer = 0;
|
||||||
for (i = 0; i < ncci->window; i++) {
|
for (i = 0; i < ncci->window; i++) {
|
||||||
if (ncci->xmit_handles[i].PktId == hh->id) {
|
if (ncci->xmit_handles[i].PktId == hh->id) {
|
||||||
if (ncci->xmit_handles[i].pkt)
|
if (ncci->xmit_handles[i].pkt)
|
||||||
|
@ -917,7 +978,8 @@ static void ncciDataConf(struct mNCCI *ncci, struct mc_buf *mc)
|
||||||
ncci->xmit_handles[i].PktId = 0;
|
ncci->xmit_handles[i].PktId = 0;
|
||||||
ncci->dlbusy = 0;
|
ncci->dlbusy = 0;
|
||||||
pthread_mutex_unlock(&ncci->lock);
|
pthread_mutex_unlock(&ncci->lock);
|
||||||
AnswerDataB3Req(ncci, mc, CapiNoError);
|
if (do_answer)
|
||||||
|
AnswerDataB3Req(ncci, mc, CapiNoError);
|
||||||
SendDataB3Down(ncci, 0);
|
SendDataB3Down(ncci, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1043,8 +1105,15 @@ static int ncciSendMessage(struct mNCCI *ncci, uint8_t cmd, uint8_t subcmd, stru
|
||||||
free_mc_buf(mc);
|
free_mc_buf(mc);
|
||||||
ret = CapiNoError;
|
ret = CapiNoError;
|
||||||
}
|
}
|
||||||
|
} else if (cmd == CAPI_DATA_TTY) {
|
||||||
|
if (ncci->ncci_m.state == ST_NCCI_N_ACT) {
|
||||||
|
ret = ncciDataReq(ncci, mc);
|
||||||
|
} else {
|
||||||
|
ret = CapiMessageNotSupportedInCurrentState;
|
||||||
|
wprint("NCCI %06x: DATA_TTY_REQ - but but NCCI state %s\n", ncci->ncci,
|
||||||
|
str_st_ncci[ncci->ncci_m.state]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// capi_message2cmsg(cmsg, skb->data);
|
|
||||||
ret = ncciGetCmsg(ncci, cmd, subcmd, mc);
|
ret = ncciGetCmsg(ncci, cmd, subcmd, mc);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1052,7 +1121,22 @@ static int ncciSendMessage(struct mNCCI *ncci, uint8_t cmd, uint8_t subcmd, stru
|
||||||
|
|
||||||
int ncciB3Data(struct BInstance *bi, struct mc_buf *mc)
|
int ncciB3Data(struct BInstance *bi, struct mc_buf *mc)
|
||||||
{
|
{
|
||||||
return ncciSendMessage(bi->b3data, mc->cmsg.Command, mc->cmsg.Subcommand, mc);
|
struct mNCCI *ncci = bi->b3data;
|
||||||
|
|
||||||
|
if (mc->cmsg.Command == CAPI_CONNECT_B3 && mc->cmsg.Subcommand == CAPI_REQ) {
|
||||||
|
if (ncci)
|
||||||
|
wprint("NCCI %06x: already assigned\n", ncci->ncci);
|
||||||
|
else {
|
||||||
|
ncci = ConnectB3Request(bi->lp, mc);
|
||||||
|
bi->b3data = ncci;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!ncci) {
|
||||||
|
wprint("No NCCI asigned for PCLI %04x\n", bi->lp->plci);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return ncciSendMessage(ncci, mc->cmsg.Command, mc->cmsg.Subcommand, mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ncciB3Message(struct mNCCI *ncci, struct mc_buf *mc)
|
int ncciB3Message(struct mNCCI *ncci, struct mc_buf *mc)
|
||||||
|
@ -1197,9 +1281,12 @@ int recvBdirect(struct BInstance *bi, struct mc_buf *mc)
|
||||||
bi->b3data = ncci;
|
bi->b3data = ncci;
|
||||||
}
|
}
|
||||||
FsmEvent(&ncci->ncci_m, EV_DL_ESTABLISH_CONF, mc);
|
FsmEvent(&ncci->ncci_m, EV_DL_ESTABLISH_CONF, mc);
|
||||||
mc->len = 520;
|
if (ncci->l1trans) {
|
||||||
memset(&mc->rb[8], 0x55, 512);
|
/* prefill FIFO 64 ms */
|
||||||
ncciDataInd(ncci, hh->prim, mc);
|
mc->len = 520;
|
||||||
|
memset(&mc->rb[8], 0x55, 512);
|
||||||
|
ncciDataInd(ncci, hh->prim, mc);
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case PH_ACTIVATE_IND:
|
case PH_ACTIVATE_IND:
|
||||||
|
@ -1211,7 +1298,8 @@ int recvBdirect(struct BInstance *bi, struct mc_buf *mc)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
} else
|
} else
|
||||||
bi->b3data = ncci;
|
bi->b3data = ncci;
|
||||||
}
|
} else
|
||||||
|
dprint(MIDEBUG_NCCI, "NCCI %06x: %s on existing NCCIx\n", ncci->ncci, _mi_msg_type2str(hh->prim));
|
||||||
FsmEvent(&ncci->ncci_m, EV_DL_ESTABLISH_IND, mc);
|
FsmEvent(&ncci->ncci_m, EV_DL_ESTABLISH_IND, mc);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue