/* m_capi.h * * Author Karsten Keil * * Copyright 2011 by Karsten Keil * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE * version 2.1 as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU LESSER GENERAL PUBLIC LICENSE for more details. * */ #ifndef _M_CAPI_H #define _M_CAPI_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "mc_buffer.h" #include "../lib/include/fsm.h" #include "../lib/include/debug.h" /* SOme globals */ extern int KeepTemporaryFiles; extern char *TempDirectory; struct mApplication; struct mPLCI; struct lPLCI; struct mNCCI; struct pController; struct lController; struct BInstance; struct Bprotocol { uint16_t B1; uint16_t B2; uint16_t B3; unsigned char B1cfg[16]; unsigned char B2cfg[16]; unsigned char B3cfg[132]; }; typedef int (BDataTrans_t)(struct BInstance *, struct mc_buf *); enum BType { BType_None = 0, BType_Direct = 1, BType_Fax = 2 }; struct BInstance { int nr; int usecnt; int proto; int fd; enum BType type; uint16_t DownId; /* Ids for send down messages */ uint16_t UpId; /* Ids for send up messages */ struct pController *pc; struct lPLCI *lp; void *b3data; BDataTrans_t *from_down; BDataTrans_t *from_up; pthread_t tid; struct pollfd pfd[2]; int cpipe[2]; sem_t wait; unsigned int running:1; unsigned int waiting:1; }; int OpenBInstance(struct BInstance *, struct lPLCI *, enum BType); int CloseBInstance(struct BInstance *); struct capi_profile { uint16_t ncontroller; /* number of installed controller */ uint16_t nbchannel; /* number of B-Channels */ uint32_t goptions; /* global options */ uint32_t support1; /* B1 protocols support */ uint32_t support2; /* B2 protocols support */ uint32_t support3; /* B3 protocols support */ uint32_t reserved[6]; /* reserved */ uint32_t manu[5]; /* manufacturer specific information */ }; /* physical controller access */ struct pController { int mNr; int enable; struct mISDN_devinfo devinfo; struct capi_profile profile; uint32_t L3Proto; uint32_t L3Flags; struct mlayer3 *l3; struct lController *lClist; struct mPLCI *plciL; /* List of PLCIs */ int appCnt; int BImax; /* Nr of BInstances */ struct BInstance *BInstances; /* Array of BInstances [0 ... BImax - 1] */ uint32_t InfoMask; /* Listen info mask all active applications */ uint32_t CIPmask; /* Listen CIP mask all active applications */ uint32_t CIPmask2; /* Listen CIP mask 2 all active applications */ }; struct pController *get_mController(int); struct pController *get_cController(int); struct BInstance *ControllerSelChannel(struct pController *, int, int); int OpenLayer3(struct pController *); /* This is a struct for the logical controller per application, also has the listen statemachine */ struct lController { struct lController *nextC; struct lController *nextA; int refc; /* refcount */ struct pController *Contr; /* pointer to the physical controler */ struct mApplication *Appl; /* pointer to the CAPI application */ struct FsmInst listen_m; /* Listen state machine */ uint32_t InfoMask; /* Listen info mask */ uint32_t CIPmask; /* Listen CIP mask */ uint32_t CIPmask2; /* Listen CIP mask 2 */ }; /* listen.c */ struct lController *get_lController(struct mApplication *, int); void init_listen(void); void free_listen(void); struct lController *addlController(struct mApplication *, struct pController *, int); void rm_lController(struct lController *lc); int listenRequest(struct lController *, struct mc_buf *); struct mApplication { struct mApplication *next; int refc; /* refcount */ int fd; /* Filedescriptor for CAPI messages */ struct lController *contL; /* list of controllers */ uint16_t AppId; uint16_t MsgId; /* next message number */ int MaxB3Con; int MaxB3Blk; int MaxB3Size; }; struct mApplication *RegisterApplication(uint16_t, uint32_t, uint32_t, uint32_t); void ReleaseApplication(struct mApplication *); int PutMessageApplication(struct mApplication *, struct mc_buf *); void SendMessage2Application(struct mApplication *, struct mc_buf *); void SendCmsg2Application(struct mApplication *, struct mc_buf *); void SendCmsgAnswer2Application(struct mApplication *, struct mc_buf *, uint16_t); int ListenController(struct pController *); struct mPLCI { struct mPLCI *next; uint32_t plci; /* PLCI ID */ int pid; /* L3 pid */ struct pController *pc; int nAppl; struct lPLCI *lPLCIs; unsigned int alerting:1; unsigned int outgoing:1; }; /* PLCI state flags */ struct mPLCI *new_mPLCI(struct pController *, int, struct lPLCI *); int free_mPLCI(struct mPLCI *); void plciDetachlPLCI(struct lPLCI *); struct mPLCI *getPLCI4Id(struct pController *, uint32_t); struct lPLCI *get_lPLCI4Id(struct mPLCI *, uint16_t); struct mPLCI *getPLCI4pid(struct pController *, int); int mPLCISendMessage(struct lController *, struct mc_buf *); int plciL4L3(struct mPLCI *, int, struct l3_msg *); int plci_l3l4(struct mPLCI *, int, struct l3_msg *); struct lPLCI { struct lPLCI *next; uint32_t plci; /* PLCI ID */ int pid; /* L3 pid */ struct lController *lc; struct mPLCI *PLCI; struct FsmInst plci_m; struct BInstance *BIlink; int NcciCnt; struct mNCCI *Nccis; int cause; int cause_loc; struct misdn_channel_info chid; struct Bprotocol Bprotocol; unsigned int l1dtmf:1; unsigned int autohangup:1; unsigned int disc_req:1; }; void init_lPLCI_fsm(void); void free_lPLCI_fsm(void); int lPLCICreate(struct lPLCI **, struct lController *, struct mPLCI *); void lPLCI_free(struct lPLCI *); void lPLCI_l3l4(struct lPLCI *, int, struct mc_buf *); uint16_t lPLCISendMessage(struct lPLCI *, struct mc_buf *); uint16_t q931CIPValue(struct mc_buf *); struct mNCCI *getNCCI4addr(struct lPLCI *, uint32_t, int); void lPLCIDelNCCI(struct mNCCI *); struct mNCCI *ConnectB3Request(struct lPLCI *, struct mc_buf *); void B3ReleaseLink(struct lPLCI *, struct BInstance *); #define GET_NCCI_EXACT 1 #define GET_NCCI_ONLY_PLCI 2 #define GET_NCCI_PLCI 3 struct _ConfQueue { uint32_t PktId; uint16_t DataHandle; uint16_t MsgId; uint16_t dlen; uint16_t sent; struct mc_buf *pkt; unsigned char *sp; }; #define CAPI_MAXDATAWINDOW 8 enum _flowmode { flmNone = 0, flmPHDATA = 1, flmIndication = 2, }; struct mNCCI { struct mNCCI *next; uint32_t ncci; struct lPLCI *lp; struct mApplication *appl; struct BInstance *BIlink; int window; struct FsmInst ncci_m; pthread_mutex_t lock; struct _ConfQueue xmit_handles[CAPI_MAXDATAWINDOW]; uint32_t recv_handles[CAPI_MAXDATAWINDOW]; enum _flowmode flowmode; uint16_t isize; uint16_t osize; uint16_t iidx; uint16_t oidx; int ridx; struct msghdr down_msg; struct iovec down_iv[3]; struct mISDNhead down_header; struct msghdr up_msg; struct iovec up_iv[2]; unsigned char up_header[30]; unsigned int dtmflisten:1; unsigned int l1direct:1; unsigned int l2trans:1; unsigned int l3trans:1; unsigned int dlbusy:1; }; void init_ncci_fsm(void); void free_ncci_fsm(void); struct mNCCI *ncciCreate(struct lPLCI *); void ncciFree(struct mNCCI *); void ncciCmsgHeader(struct mNCCI *ncci, struct mc_buf *mc, uint8_t, uint8_t); int recvBdirect(struct BInstance *, struct mc_buf *); int ncciB3Data(struct BInstance *, struct mc_buf *); int ncciB3Message(struct mNCCI *, struct mc_buf *); void ncciReleaseLink(struct mNCCI *); void ncciDel_lPlci(struct mNCCI *); int ncciL4L3(struct mNCCI *, uint32_t, int, int, void *, struct mc_buf *); void AnswerDataB3Req(struct mNCCI *, struct mc_buf *, uint16_t); #ifdef USE_SOFTFAX int FaxRecvBData(struct BInstance *, struct mc_buf *); int FaxB3Message(struct BInstance *, struct mc_buf *); void FaxReleaseLink(struct BInstance *); #endif #define MC_BUF_ALLOC(a) if (!(a = alloc_mc_buf())) {eprint("Cannot allocate mc_buff\n");return;} #define CMSGCMD(cm) CAPICMD((cm)->Command, (cm)->Subcommand) /* Debug MASK */ #define MC_DEBUG_POLL 0x01 #define MC_DEBUG_CONTROLLER 0x02 #define MC_DEBUG_CAPIMSG 0x04 #define MC_DEBUG_STATES 0x08 #define MC_DEBUG_PLCI 0x10 #define MC_DEBUG_NCCI 0x20 #define MC_DEBUG_NCCI_DATA 0x40 #define MIDEBUG_POLL (MC_DEBUG_POLL << 24) #define MIDEBUG_CONTROLLER (MC_DEBUG_CONTROLLER << 24) #define MIDEBUG_CAPIMSG (MC_DEBUG_CAPIMSG << 24) #define MIDEBUG_STATES (MC_DEBUG_STATES << 24) #define MIDEBUG_PLCI (MC_DEBUG_PLCI << 24) #define MIDEBUG_NCCI (MC_DEBUG_NCCI << 24) #define MIDEBUG_NCCI_DATA (MC_DEBUG_NCCI_DATA << 24) void mCapi_cmsg2str(struct mc_buf *); void mCapi_message2str(struct mc_buf *); /* missing capi errors */ #define CapiMessageNotSupportedInCurrentState 0x2001 #define CapiIllController 0x2002 #define CapiNoPlciAvailable 0x2003 #define CapiIllMessageParmCoding 0x2007 #define CapiB1ProtocolNotSupported 0x3001 #define CapiB2ProtocolNotSupported 0x3002 #define CapiB3ProtocolNotSupported 0x3003 #define CapiB1ProtocolParameterNotSupported 0x3004 #define CapiB2ProtocolParameterNotSupported 0x3005 #define CapiB3ProtocolParameterNotSupported 0x3006 #define CapiProtocolCombinationNotSupported 0x3007 #define CapiNCPINotSupported 0x3008 #define CapiProtocolErrorLayer1 0x3301 #define CapiProtocolErrorLayer2 0x3302 #define CapiProtocolErrorLayer3 0x3303 #define FAX_B3_FORMAT_SFF 0 #define FAX_B3_FORMAT_PLAIN 1 #define FAX_B3_FORMAT_PCX 2 #define FAX_B3_FORMAT_DCX 3 #define FAX_B3_FORMAT_TIFF 4 #define FAX_B3_FORMAT_ASCII 5 #define FAX_B3_FORMAT_EXT_ANSI 6 #define FAX_B3_FORMAT_BINARY 7 /* Info mask bits */ #define CAPI_INFOMASK_CAUSE 0x0001 #define CAPI_INFOMASK_DATETIME 0x0002 #define CAPI_INFOMASK_DISPLAY 0x0004 #define CAPI_INFOMASK_USERUSER 0x0008 #define CAPI_INFOMASK_PROGRESS 0x0010 #define CAPI_INFOMASK_FACILITY 0x0020 #define CAPI_INFOMASK_CHARGE 0x0040 #define CAPI_INFOMASK_CALLEDPN 0x0080 #define CAPI_INFOMASK_CHANNELID 0x0100 #define CAPI_INFOMASK_EARLYB3 0x0200 #define CAPI_INFOMASK_REDIRECT 0x0400 #define CAPI_INFOMASK_COMPLETE 0x1000 #define CAPIMSG_REQ_DATAHANDLE(m) (m[18] | (m[19]<<8)) #define CAPIMSG_RESP_DATAHANDLE(m) (m[12] | (m[13]<<8)) #define CAPIMSG_REQ_FLAGS(m) (m[20] | (m[21]<<8)) #define CAPI_B3_DATA_IND_HEADER_SIZE ((4 == sizeof(void *)) ? 22 : 30) /* some helper */ static inline int capiEncodeWord(unsigned char *p, uint16_t i) { *p++ = i; *p++ = i >> 8; return 2; } static inline int capiEncodeDWord(unsigned char *p, uint32_t i) { *p++ = i; *p++ = i >> 8; *p++ = i >> 16; *p++ = i >> 24; return 4; } int capiEncodeFacIndSuspend(unsigned char *, uint16_t); #endif