Merged latest changes from trunk.
This commit is contained in:
parent
e25f33a595
commit
2384c8d7cc
31
CHANGES
31
CHANGES
|
@ -1,6 +1,37 @@
|
|||
CHANGES
|
||||
=======
|
||||
|
||||
HEAD
|
||||
------------------
|
||||
- added dialplan variables ISDNPI1 and ISDNPI2
|
||||
- Support for 'divastreaming' available (Diva 4PRI PCI, Diva 2PRI PCI,
|
||||
Diva 4PRI HS PCIe, Diva 2PRI HS PCIe, Diva 1PRI HS PCIe,
|
||||
Diva 8PRI PCIe FS, Diva 4PRI PCIe FS)
|
||||
- Fixed memory leak in chat_play if using with 's' option
|
||||
- Add 'econtransitconn' configurations parameter. Allows to preserve
|
||||
EC for transit connections
|
||||
- added variable DISCONNECT_IND_REASON to get real reason code from CAPI
|
||||
- added capicommand(keypad)
|
||||
- added log of FACILITY_IND for call deflect suplementary service
|
||||
- malloc,strdup,free -> ast_(malloc,strdup,free)
|
||||
- Use Diva streaming for NULL PLCI and for resource PLCI
|
||||
- Resolved http://www.ipphoneforum.eu/showthread.php?t=220051
|
||||
- Use Diva QSIG CAPI extensions for processing of Calling Party Name
|
||||
- Add Slinear
|
||||
- Add HD voice using G.722, Siren7, Siren14 and Slinear16
|
||||
- added faxdestination= to capi.conf to configure custom context,exten,prio.
|
||||
- allow capicommand option separator "|" and ",".
|
||||
- Add MWI server
|
||||
- Add MWI client
|
||||
- Improved call distribution algorithm for outgoing calls
|
||||
- Add 'capi ifcstate', 'capi exec', 'capi show resources' and
|
||||
'chat manage remove' CLI commands
|
||||
- Add AMI 'Capichat[List,Mute,Unmute,Remove]' and 'CapiCommand' actions and
|
||||
Capichat[List,ListComplete,Join,Leave,End] events
|
||||
- Add device state events for char rooms (capichat:[roomname]) and for
|
||||
interface state (ISDN/I[N]/congestion)
|
||||
- Add access to Diva trace driver
|
||||
|
||||
chan_capi-1.1.5
|
||||
------------------
|
||||
- corrected check for Info value on CONNECT_B3_CONF
|
||||
|
|
59
Makefile
59
Makefile
|
@ -18,6 +18,10 @@
|
|||
|
||||
OSNAME=${shell uname}
|
||||
|
||||
DIVA_STREAMING=0
|
||||
DIVA_STATUS=0
|
||||
DIVA_VERBOSE=0
|
||||
|
||||
USE_OWN_LIBCAPI=yes
|
||||
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
|
@ -78,6 +82,16 @@ INCLUDE=
|
|||
LIBLINUX=-lcapi20
|
||||
endif
|
||||
|
||||
ifeq (${DIVA_STREAMING},1)
|
||||
INCLUDE += -I./divastreaming -I./divastreaming/..
|
||||
endif
|
||||
|
||||
ifeq (${DIVA_STATUS},1)
|
||||
INCLUDE += -I./divastatus -I./divastatus/..
|
||||
endif
|
||||
|
||||
INCLUDE += -I./divaverbose
|
||||
|
||||
DEBUG=-g #-pg
|
||||
INCLUDE+= -I$(ASTERISK_HEADER_DIR)
|
||||
ifndef C4B
|
||||
|
@ -100,6 +114,20 @@ CFLAGS+=$(OPTIMIZE)
|
|||
CFLAGS+=-O2
|
||||
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
|
||||
CFLAGS+=$(shell if uname -m | grep -q "ppc\|arm\|s390"; then echo "-fsigned-char"; fi)
|
||||
ifeq (${DIVA_STREAMING},1)
|
||||
CFLAGS += -DDIVA_STREAMING=1
|
||||
endif
|
||||
ifeq (${DIVA_STATUS},1)
|
||||
CFLAGS += -DDIVA_STATUS=1
|
||||
|
||||
CFLAGS+=$(shell echo '\#include <sys/inotify.h>' > /tmp/test.c 2>/dev/null && \
|
||||
echo 'int main(int argc,char**argv){if(inotify_init()>=0)return 0; return 1;}' >> /tmp/test.c 2>/dev/null && \
|
||||
$(CC) /tmp/test.c -o /tmp/test && /tmp/test >/dev/null 2>&1 && echo '-DCC_USE_INOTIFY=1'; rm -f /tmp/test.c /tmp/test)
|
||||
endif
|
||||
ifeq (${DIVA_VERBOSE},1)
|
||||
CFLAGS += -DDIVA_VERBOSE=1
|
||||
endif
|
||||
|
||||
|
||||
LIBS=-ldl -lpthread -lm
|
||||
CC=gcc
|
||||
|
@ -109,12 +137,32 @@ SHAREDOS=chan_capi.so
|
|||
|
||||
OBJECTS=chan_capi.o chan_capi_utils.o chan_capi_rtp.o chan_capi_command.o xlaw.o dlist.o \
|
||||
chan_capi_qsig_core.o chan_capi_qsig_ecma.o chan_capi_qsig_asn197ade.o \
|
||||
chan_capi_qsig_asn197no.o chan_capi_supplementary.o chan_capi_chat.o
|
||||
chan_capi_qsig_asn197no.o chan_capi_supplementary.o chan_capi_chat.o \
|
||||
chan_capi_mwi.o chan_capi_cli.o chan_capi_ami.o chan_capi_management_common.o \
|
||||
chan_capi_devstate.o
|
||||
|
||||
ifeq (${USE_OWN_LIBCAPI},yes)
|
||||
OBJECTS += libcapi20/convert.o libcapi20/capi20.o libcapi20/capifunc.o
|
||||
endif
|
||||
|
||||
ifeq (${DIVA_STREAMING},1)
|
||||
OBJECTS += divastreaming/diva_streaming_idi_host_ifc_impl.o \
|
||||
divastreaming/diva_streaming_idi_host_rx_ifc_impl.o \
|
||||
divastreaming/diva_streaming_manager.o \
|
||||
divastreaming/diva_streaming_messages.o \
|
||||
divastreaming/segment_alloc.o \
|
||||
divastreaming/chan_capi_divastreaming_utils.o \
|
||||
divastreaming/runtime.o
|
||||
endif
|
||||
|
||||
ifeq (${DIVA_STATUS},1)
|
||||
OBJECTS += divastatus/divastatus.o
|
||||
endif
|
||||
|
||||
ifeq (${DIVA_VERBOSE},1)
|
||||
OBJECTS += divaverbose/divaverbose.o
|
||||
endif
|
||||
|
||||
CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
|
||||
|
||||
CFLAGS+=-DCRYPTO
|
||||
|
@ -131,6 +179,15 @@ clean:
|
|||
rm -f config.h
|
||||
rm -f *.so *.o
|
||||
rm -f libcapi20/*.o
|
||||
rm -f divastreaming/*.o
|
||||
rm -f divastatus/*.o
|
||||
rm -f divaverbose/*.o
|
||||
|
||||
distclean: clean
|
||||
rm -f $(MODULES_DIR)/$(SHAREDOS)
|
||||
|
||||
sysclean: distclean
|
||||
rm -f $(MODULES_DIR)/*.so
|
||||
|
||||
config.h:
|
||||
./create_config.sh "$(ASTERISK_HEADER_DIR)"
|
||||
|
|
118
README
118
README
|
@ -98,6 +98,7 @@ The Dial string
|
|||
(Useful if additional digits should be send afterwards or together
|
||||
with 'b' to get the dialtone and then send the number, e.g., if
|
||||
no progress tones are available)
|
||||
'c' : do not send sending complete
|
||||
's' : activate 'stay-online': do not disconnect CAPI connection on hangup.
|
||||
This is needed to give additional commands like CCBS after hangup.
|
||||
To really hang up the CAPI connection, use either capicommand(hangup)
|
||||
|
@ -138,6 +139,16 @@ capi show channels:
|
|||
capi chatinfo:
|
||||
Show status of CAPI CHAT.
|
||||
|
||||
capi ifcstate:
|
||||
Show state of interfaces. (Diva only, chan_capi
|
||||
compiled with 'make DIVA_STATUS=1')
|
||||
|
||||
capi show resources:
|
||||
Show resources in use.
|
||||
|
||||
capi exec:
|
||||
'capi exec CHANNEL command,parameter1,parameter2,....,parameterN'
|
||||
Exec capicommand 'command' for selected channel.
|
||||
|
||||
CAPI command application
|
||||
========================================
|
||||
|
@ -148,27 +159,27 @@ With this application, special CAPI commands and features can be used.
|
|||
Call Deflection:
|
||||
Forwards an unanswered call to another number.
|
||||
Example:
|
||||
exten => s,1,capicommand(deflect|12345678)
|
||||
exten => s,1,capicommand(deflect,12345678)
|
||||
|
||||
Fax receive:
|
||||
Receives a fax using CAPI.
|
||||
Example:
|
||||
exten => s,1,capicommand(receivefax|/tmp/${UNIQUEID}|+49 6137 555123|Asterisk|kX)
|
||||
exten => s,1,capicommand(receivefax,/tmp/${UNIQUEID},+49 6137 555123,Asterisk,kX)
|
||||
(more see below)
|
||||
|
||||
Fax send:
|
||||
Sends a fax using CAPI.
|
||||
Example:
|
||||
exten => s,1,capicommand(sendfax|/path/to/faxfile.sff|+49 6137 555123|Asterisk)
|
||||
exten => s,1,capicommand(sendfax,/path/to/faxfile.sff,+49 6137 555123,Asterisk)
|
||||
(more see below)
|
||||
|
||||
Enable/Disable echosquelch:
|
||||
Enables or disable a very primitive echo suppressor.
|
||||
Disable this option before you start recording voicemail or your files may get choppy.
|
||||
Example:
|
||||
exten => s,1,capicommand(echosquelch|yes)
|
||||
exten => s,1,capicommand(echosquelch,yes)
|
||||
or
|
||||
exten => s,1,capicommand(echosquelch|no)
|
||||
exten => s,1,capicommand(echosquelch,no)
|
||||
|
||||
Enable/Disable echocancel:
|
||||
Enables or disables echo-cancel provided by CAPI driver/hardware.
|
||||
|
@ -176,9 +187,22 @@ Enable/Disable echocancel:
|
|||
by a non-CAPI application. After hangup, this setting is restored to the value
|
||||
set in capi.conf.
|
||||
Example:
|
||||
exten => s,1,capicommand(echocancel|yes)
|
||||
exten => s,1,capicommand(echocancel,yes)
|
||||
or
|
||||
exten => s,1,capicommand(echocancel|no)
|
||||
exten => s,1,capicommand(echocancel,no)
|
||||
|
||||
By default chan_capi deactivates echo-cancel for transit connections
|
||||
(Dial command called from existing call). You can use 'econtransitconn'
|
||||
configurations parameter (capi.conf) to change this behavior:
|
||||
econtransitconn=0 ; Deactivate EC on transit connections
|
||||
econtransitconn=1 ; Deactivate EC on secondary call of transit connection only
|
||||
econtransitconn=2 ; Deactivate EC on primary call of transit connection only
|
||||
econtransitconn=3 ; Do not deactivate EC on transit connections
|
||||
|
||||
Send Keypad Facility:
|
||||
Send Keypad Faciliaty information.
|
||||
Example:
|
||||
exten => s,1,capicommand(keypad,<digits>)
|
||||
|
||||
Malicious Call Identification:
|
||||
Reports a call of malicious nature.
|
||||
|
@ -193,18 +217,18 @@ Hold:
|
|||
Example:
|
||||
exten => s,1,capicommand(hold)
|
||||
or
|
||||
exten => s,1,capicommand(hold|MYHOLDVAR)
|
||||
exten => s,1,capicommand(hold,MYHOLDVAR)
|
||||
|
||||
Holdtype:
|
||||
Sets the type of 'hold'. When Asterisk wants to put the call on hold, the specified method
|
||||
will be used.
|
||||
Example:
|
||||
exten => s,1,capicommand(holdtype|local) ;no hold, Asterisk can play MOH
|
||||
exten => s,1,capicommand(holdtype,local) ;no hold, Asterisk can play MOH
|
||||
or
|
||||
exten => s,1,capicommand(holdtype|hold) ;ISDN-HOLD
|
||||
exten => s,1,capicommand(holdtype,hold) ;ISDN-HOLD
|
||||
or
|
||||
; not yet implemented
|
||||
exten => s,1,capicommand(holdtype|notify) ;notify the peer only, Asterisk can play MOH
|
||||
exten => s,1,capicommand(holdtype,notify) ;notify the peer only, Asterisk can play MOH
|
||||
|
||||
|
||||
Retrieve:
|
||||
|
@ -213,12 +237,12 @@ Retrieve:
|
|||
Example:
|
||||
exten => s,1,capicommand(retrieve)
|
||||
or
|
||||
exten => s,1,capicommand(retrieve|${MYHOLDVAR})
|
||||
exten => s,1,capicommand(retrieve,${MYHOLDVAR})
|
||||
|
||||
ECT:
|
||||
Explicit Call Transfer of the call on hold (must put call on hold first!)
|
||||
Example:
|
||||
exten => s,1,capicommand(ect|${MYHOLDVAR})
|
||||
exten => s,1,capicommand(ect,${MYHOLDVAR})
|
||||
or
|
||||
[macro-capiect]
|
||||
exten => s,1,capicommand(ect)
|
||||
|
@ -228,13 +252,13 @@ ECT:
|
|||
exten => s,3,Dial(CAPI/contr1/1234,60,M(capiect))
|
||||
Note: Normaly a PBX needs 'implicit call transfer', which is done by default
|
||||
with this command. But if the line needs real 'explicit call transfer', use
|
||||
exten => s,1,capicommand(ect|x)
|
||||
exten => s,1,capicommand(ect,x)
|
||||
instead.
|
||||
|
||||
3PTY:
|
||||
Initiates a Three-Party Conference (must have one call on hold and one active call!).
|
||||
Example:
|
||||
exten => s,1,capicommand(3pty_begin|${MYHOLDVAR})
|
||||
exten => s,1,capicommand(3pty_begin,${MYHOLDVAR})
|
||||
or
|
||||
[macro-capi3pty]
|
||||
exten => s,1,capicommand(3pty_begin)
|
||||
|
@ -261,9 +285,9 @@ Set local party to 'busy' or 'free':
|
|||
about the status of the extension who started the callback.
|
||||
By default, chan_capi assumes 'free', but you can change that
|
||||
with:
|
||||
exten => s,1,capicommand(ccpartybusy|${CCLINKAGEID}|yes)
|
||||
exten => s,1,capicommand(ccpartybusy,${CCLINKAGEID},yes)
|
||||
or
|
||||
exten => s,1,capicommand(ccpartybusy|${CCLINKAGEID}|no)
|
||||
exten => s,1,capicommand(ccpartybusy,${CCLINKAGEID},no)
|
||||
|
||||
Call completion on subscriber busy (CCBS):
|
||||
To receive a callback when the dialed and busy party becomes free, aka
|
||||
|
@ -273,7 +297,7 @@ Call completion on subscriber busy (CCBS):
|
|||
exten => s,2,Dial(CAPI/contr1/123456,60,g) ;'g' to go-on with the dialplan on busy.
|
||||
exten => s,3,NoOp(${CCLINKAGEID}) ;if this variable now contains a number, CCBS is possible.
|
||||
;here you can ask the caller if CCBS shall be activated...
|
||||
exten => s,4,capicommand(ccbs|${CCLINKAGEID}|<context>|<exten>|<priority>)
|
||||
exten => s,4,capicommand(ccbs,${CCLINKAGEID},<context>,<exten>,<priority>)
|
||||
exten => s,5,NoOp(${CCBSSTATUS}) ;if CCBS was successfully enabled, it is set to "ACTIVATED".
|
||||
If the remote party becomes 'non-busy', the network initiates the callback that will be
|
||||
sent to the provided context/exten/priority. Of course, this only happens if your local
|
||||
|
@ -285,15 +309,15 @@ Call completion on subscriber busy (CCBS):
|
|||
Deactivate CCBS:
|
||||
To deactivate a previously activated CCBS, use the following command:
|
||||
Example:
|
||||
exten => s,1,capicommand(ccbsstop|${CCLINKAGEID})
|
||||
exten => s,1,capicommand(ccbsstop,${CCLINKAGEID})
|
||||
|
||||
Chat (MeetMe/Conference):
|
||||
See also README.media for details!
|
||||
If the CAPI card/driver supports it, the caller can be put into a chat-room:
|
||||
(This uses the DSPs onboard a Dialogic(R) Diva(R) Rev.2 Media Board.)
|
||||
exten => s,1,capicommand(chat|<roomname>|<options>|controller)
|
||||
exten => s,1,capicommand(chat,<roomname>,<options>,controller)
|
||||
Example:
|
||||
exten => s,1,capicommand(chat|salesmeeting|m|1,3-6)
|
||||
exten => s,1,capicommand(chat,salesmeeting,m,1,3-6)
|
||||
Possible options:
|
||||
'm' = The first caller will get music-on-hold until second caller arrives.
|
||||
'h<sec>' = Hangup after <sec> seconds if caller is alone in conference.
|
||||
|
@ -372,19 +396,19 @@ Short HOWTO of capicommand(receivefax...) and capicommand(sendfax...):
|
|||
For those of you who have a CAPI card with an on-board DSP (like Dialogic(R) Diva(R) Media Boards),
|
||||
this allows you to receive/send faxes.
|
||||
|
||||
capicommand(receivefax|<filename>[|<stationid>|<headline>|<options>]):
|
||||
capicommand(receivefax,<filename>[,<stationid>,<headline>,<options>]):
|
||||
-------------------------------------------------------------------------
|
||||
If you want to answer a channel in fax mode, use capicommand(receivefax|...)
|
||||
If you want to answer a channel in fax mode, use capicommand(receivefax,...)
|
||||
instead of Answer(). If you use Answer(), you will be in voice mode.
|
||||
If the hardware DSP detects fax tone, you can switch from voice to fax mode
|
||||
by calling capicommand(receivefax|...).
|
||||
by calling capicommand(receivefax,...).
|
||||
The parameter <filename> is mandatory and the parameters <stationid>,
|
||||
<headline> and <options> are optional.
|
||||
By default, if fax reception was not successful, the file is deleted. If you want even
|
||||
partly received or broken fax files, use 'k' for "keep bad fax" in the <options>:
|
||||
capicommand(receivefax|/tmp/${UNIQUEID}|+123456789||k)
|
||||
capicommand(receivefax,/tmp/${UNIQUEID},+123456789,,k)
|
||||
You can activate extended fax support by 'X' in the <options>:
|
||||
capicommand(receivefax|/tmp/${UNIQUEID}|+123456789||X)
|
||||
capicommand(receivefax,/tmp/${UNIQUEID},+123456789,X)
|
||||
Please read details on extended fax options in README.Diva.fax.
|
||||
|
||||
To enable fax tone detection and redirect to extension 'fax', use config variable
|
||||
|
@ -402,11 +426,11 @@ exten => 124,1,Goto(handle_fax,s,1)
|
|||
exten => fax,1,Goto(handle_fax,s,1)
|
||||
|
||||
[handle_fax]
|
||||
exten => s,1,capicommand(receivefax|/tmp/${UNIQUEID}[|<stationid>|<headline>|<options>])
|
||||
exten => s,1,capicommand(receivefax,/tmp/${UNIQUEID}[,<stationid>,<headline>,<options>])
|
||||
exten => s,2,Hangup()
|
||||
exten => h,1,deadagi,fax.php // Run sfftobmp and mail it.
|
||||
|
||||
The output of capicommand(receivefax|...) is a SFF file.
|
||||
The output of capicommand(receivefax,...) is a SFF file.
|
||||
Use sfftobmp to convert it.
|
||||
With a Dialogic(R) Diva(R) Media Board, the following features are provided:
|
||||
- fax up to 33600
|
||||
|
@ -415,12 +439,12 @@ With a Dialogic(R) Diva(R) Media Board, the following features are provided:
|
|||
- JPEG Compression is disabled (not tested yet)
|
||||
See README.Diva.fax for more details and description of all options.
|
||||
|
||||
capicommand(sendfax|<filename>[|<stationid>|<headline>|<options>]):
|
||||
capicommand(sendfax,<filename>[,<stationid>,<headline>,<options>]):
|
||||
------------------------------------------------------------
|
||||
To send a fax, you can use the same mechanism like with receivefax.
|
||||
Just replace the <filename> with the path to the .SFF file to send.
|
||||
You can activate extended fax support by 'X' in the <options>:
|
||||
capicommand(sendfax|/tmp/${UNIQUEID}|+123456789||X)
|
||||
capicommand(sendfax,/tmp/${UNIQUEID},+123456789,,X)
|
||||
Please read details on extended fax options in README.Diva.fax.
|
||||
|
||||
After disconnect of a fax connection, the following variables
|
||||
|
@ -472,7 +496,7 @@ BCHANNELINFO
|
|||
'2' : neither B nor D-channel is used (e.g., call waiting)
|
||||
Call-Waiting: an incoming call with BCHANNELINFO not '0' cannot be accepted.
|
||||
Another connection must be dropped before accepting or use
|
||||
capicommand(deflect|<number>) to initiate call deflection to another destination.
|
||||
capicommand(deflect,<number>) to initiate call deflection to another destination.
|
||||
|
||||
CALLEDTON
|
||||
Incoming calls: 'type of number' value of the called number is saved in this variable on
|
||||
|
@ -509,7 +533,7 @@ CAPI_CIP
|
|||
instead of transfercapability.
|
||||
|
||||
CCBSSTATUS
|
||||
When using capicommand(ccbs|....), this variable is set to either "ERROR" or
|
||||
When using capicommand(ccbs,....), this variable is set to either "ERROR" or
|
||||
"ACTIVATED".
|
||||
|
||||
CCLINKAGEID
|
||||
|
@ -522,8 +546,15 @@ CONNECTEDNUMBER
|
|||
Can be set before answering and if set, the content is used for
|
||||
IE 'Connected Number' on answering.
|
||||
|
||||
DISCONNECT_IND_REASON
|
||||
When CAPI reports DISCONNECT_IND, some CAPI reason codes are not set
|
||||
in HANGUPCAUSE, because they are not valid cause codes. To also
|
||||
get those CAPI reason codes, you can check this variable on hangup.
|
||||
This is e.g. useful for reason 0x3301, which tells that the ISDN
|
||||
connection is physically broken (cable).
|
||||
|
||||
FAXEXTEN
|
||||
If chan_capi sends the call to extensions 'fax', the original extension number
|
||||
If chan_capi sends the call to configured fax extension, the original extension number
|
||||
is saved in this variable.
|
||||
|
||||
PRI_CAUSE
|
||||
|
@ -542,4 +573,25 @@ REDIRECTIONNUMBER
|
|||
If an outgoing call is redirected, this variable may be set to the
|
||||
new destination.
|
||||
|
||||
ISDNPI1 and ISDNPI2
|
||||
The two values of the information element PI (Progress Indicator).
|
||||
|
||||
Asterisk outgoing calls
|
||||
==========================================================
|
||||
|
||||
Distribution of outgoing calls is controlled by two
|
||||
configuration variables (capi.conf, controller specific).
|
||||
|
||||
hlimit - Number of reserved channels. If number of free
|
||||
channels is below the one specified by 'hlimit' value then
|
||||
no new outgoing calls are delivered to this controller.
|
||||
|
||||
slimit - If value is set for multiple belonging to same dialout group
|
||||
controllers then the outgoing calls are distributd as follows:
|
||||
Calls are delivered to the controller with smalest (in group)
|
||||
number and the amount of free channels bigger then or equal to
|
||||
one speciefied by 'slimit'. After amount of free channels for all
|
||||
included in the group controllers is decreased below one specified
|
||||
by 'slimit' value calls are distributed in rount robin fashion
|
||||
between all (in group) controllers.
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
+===================================================================+
|
||||
| HD Audio (Hight Definition Audio) |
|
||||
+===================================================================+
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Supported HD Audio vocoders |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Diva provides support for following HD Audio vocoders:
|
||||
|
||||
g722, ssiren7 siren14 and slin16
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Supported Diva Hardware |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
HD Audio support is provided by:
|
||||
Diva 4PRI PCI
|
||||
Diva 2PRI PCI
|
||||
Diva 4PRI PCIe HS
|
||||
Diva 2PRI PCIe HS
|
||||
Diva 1PRI PCIe HS
|
||||
Diva 8PRI PCIe FS 4LANE
|
||||
Diva 4PRI PCIe FS 4LANE
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| HD Audio over ISDN support |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
To activate support for HD Audio please allow all or one of HD Audio
|
||||
codecs for one or more CAPI controllers. You can do it by Diva WEB
|
||||
configuration or by edit of 'capi.conf'.
|
||||
|
||||
Diva hardware will use BC/HLC/LLC method to agree on HD Audio
|
||||
format with opposite side. In addition Diva hardware will
|
||||
perform analysis of B-channel data to determine if HD Audio
|
||||
format is signaled in band.
|
||||
|
||||
Dependent on this procedire Diva will use HD Audio format
|
||||
or change to G.711 if HD Audio is not supported by opposite side.
|
||||
|
||||
Diva hardware will always convert media to one requested by chan_capi format.
|
||||
Following conversions are performed automatically:
|
||||
|
||||
G.711 <-> HD Audio in case chan_capi uses HD Audio but opposite side not
|
||||
HD Audio <-> G.711/GSM/... in case opposite side uses HD Audio but
|
||||
chan_capi uses other codec
|
||||
|
||||
Examples of HD Audio operation:
|
||||
|
||||
G.722 <-> SLINEAR16
|
||||
G.722 <-> siren14
|
||||
G.722 <-> siren7
|
||||
G.722 <-> G.722
|
||||
|
||||
Using automatic convertion this is possible always use HD Audio on internel (IP) network and do not case
|
||||
about used on the line (ISDN) format.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| HD Audio support for IP conference endpoints |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
To activate HD Audio support for IP conferencing please add one or
|
||||
mode HD Audio codecs to codeclist of capi command 'resource'.
|
||||
Please read README.media for details on 'resource'
|
||||
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Conferencing between HD and NB Audio endpoints |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
In case of conference with HD and NB (Narrow Band) Audio endpoints
|
||||
the quelity of HD endpoints is preserved
|
||||
|
|
@ -212,7 +212,7 @@ Reception of fax documents
|
|||
You can use the Dialogic (R) Diva(R) chan_capi configuration to activate fax support ("Fax detection" and "Fax detection time").
|
||||
The reception of the fax message is started using 'receivefax' capi command:
|
||||
|
||||
capicommand(receivefax|<filename>[|<stationid>|<headline>|<options>])
|
||||
capicommand(receivefax,<filename>[,<stationid>,<headline>,<options>])
|
||||
|
||||
Parameters:
|
||||
'filename' - Contains the full path and file name for the resulting fax file, mandatory
|
||||
|
@ -256,15 +256,15 @@ exten => fax,1,Goto(handle_fax,s,1) ; Fax calling tone detected, change to
|
|||
exten => i,1,Hangup() ; Received unexpected event
|
||||
|
||||
[handle_fax]
|
||||
exten => s,1,capicommand(receivefax|/tmp/${UNIQUEID}[|<stationid>|<headline>|<options>])
|
||||
exten => s,1,capicommand(receivefax,/tmp/${UNIQUEID}[,<stationid>,<headline>,<options>])
|
||||
exten => s,n,Hangup()
|
||||
exten => h,1,deadagi,fax.php ; Run sfftobmp and mail it
|
||||
|
||||
Example with Clear Channel fax support:
|
||||
|
||||
[handle_fax]
|
||||
exten => s,1,capicommand(resource|1-4) ; Assign resource PLCI (use controllers 1 to 4)
|
||||
exten => s,n,capicommand(receivefax|/tmp/${UNIQUEID}[|<stationid>|<headline>|<options>])
|
||||
exten => s,1,capicommand(resource,1-4) ; Assign resource PLCI (use controllers 1 to 4)
|
||||
exten => s,n,capicommand(receivefax,/tmp/${UNIQUEID}[,<stationid>,<headline>,<options>])
|
||||
exten => s,n,Hangup()
|
||||
exten => h,1,deadagi,fax.php ; Run sfftobmp and mail it
|
||||
|
||||
|
@ -274,7 +274,7 @@ Transmission of fax documents
|
|||
|
||||
The transmission of the fax message is started using 'sendfax' capi command:
|
||||
|
||||
capicommand(sendfax|<filename>[|<stationid>|<headline>|<options>])
|
||||
capicommand(sendfax,<filename>[,<stationid>,<headline>,<options>])
|
||||
|
||||
Parameters:
|
||||
'filename' - Contains the full path and file name to be sent, mandatory
|
||||
|
@ -309,7 +309,7 @@ Example:
|
|||
exten => 1,1,Dial(capi/ISDN1/1234512345,20,G(handle_sendfax,s,1))
|
||||
|
||||
[handle_sendfax]
|
||||
exten => s,1,capicommand(sendfax|/tmp/sendfax001.sff|1234 1234 1234|Outgoing Fax)
|
||||
exten => s,1,capicommand(sendfax,/tmp/sendfax001.sff,1234 1234 1234,Outgoing Fax)
|
||||
exten => s,n,deadagi,faxlog.php ; Log result and schedule restart if necessary
|
||||
exten => s,n,Hangup
|
||||
|
||||
|
@ -317,8 +317,8 @@ exten => s,n,Hangup
|
|||
Example with Clear Channel fax support:
|
||||
|
||||
[handle_sendfax]
|
||||
exten => s,1,capicommand(resource|1-4) ; Assign resource PLCI
|
||||
exten => s,n,capicommand(sendfax|/tmp/sendfax001.sff|1234 1234 1234|Outgoing Fax)
|
||||
exten => s,1,capicommand(resource,1-4) ; Assign resource PLCI
|
||||
exten => s,n,capicommand(sendfax,/tmp/sendfax001.sff,1234 1234 1234,Outgoing Fax)
|
||||
exten => s,n,deadagi,faxlog.php ; Log result and schedule restart if necessary
|
||||
exten => s,n,Hangup
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
+===================================================================+
|
||||
+===================================================================+
|
||||
| QSIG Abstraction |
|
||||
+===================================================================+
|
||||
|
||||
|
@ -14,6 +14,13 @@ equipment Dialogic(R) Diva(R) interfaces as well.
|
|||
The coding of the messages and the type of the transfer invoked, depends
|
||||
on the QSIG dialect and on the vendor-specific implementation of QSIG dialect.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Use Diva QSIG abstraction with chan_capi |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
To use Diva QSIG abstraction please add 'divaqsig=1' to configuration
|
||||
of CAPI controller (capi.conf).
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| QSIG abstraction |
|
||||
+-------------------------------------------------------------------+
|
||||
|
@ -21,6 +28,14 @@ on the QSIG dialect and on the vendor-specific implementation of QSIG dialect.
|
|||
Dialogic(R) Diva(R) System Release Software abstraction allows to write
|
||||
QSIG applications independent of the used QSIG dialect.
|
||||
|
||||
Name and Display information elements
|
||||
Name (Calling Pary Name, Called Party Name, Connected Party Name,
|
||||
Busy Party Name) and Display information elementss are converted to protocol
|
||||
independent format and delivered to (received from) application using
|
||||
Diva manufacturer extensions. Information elements encoded as facility array
|
||||
(for example in CONNECT_REQ) are converted in accordance with rules of active
|
||||
QSIG protocol.
|
||||
|
||||
Unassisted call transfer:
|
||||
The application can use CAPI call deflection. The Diva System Release software
|
||||
will automatically translate the call deflection request in the appropriate
|
||||
|
@ -143,7 +158,7 @@ ECT Example:
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
[macro-capiect]
|
||||
; Activate suppressor of ambient noise for consultation call
|
||||
exten => s,1,capicommand(noisesuppressor|yes)
|
||||
exten => s,1,capicommand(noisesuppressor,yes)
|
||||
; Invoke ECT command
|
||||
exten => s,n,capicommand(ect)
|
||||
|
||||
|
@ -157,7 +172,7 @@ exten => 12345,n,Playback(demo-enterkeywords,noanswer,us)
|
|||
; Accept incoming call
|
||||
exten => 12345,n,Answer
|
||||
; Activate suppressor of ambient noises for incoming call
|
||||
exten => 12345,n,capicommand(noisesuppressor|yes)
|
||||
exten => 12345,n,capicommand(noisesuppressor,yes)
|
||||
; Save PLCI of incoming call to CAPIPLCI variable
|
||||
exten => 12345,n,capicommand(getplci)
|
||||
; Set CAPIECTPLCI variable to PLCI of incoming call
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
+===================================================================+
|
||||
| Diva streaming |
|
||||
+-------------------------------------------------------------------+
|
||||
| |
|
||||
| What is Diva streaming |
|
||||
| How to activate Diva streaming support in chan_capi |
|
||||
| Performance metrics on chan_capi |
|
||||
| Supported hardware |
|
||||
| |
|
||||
+===================================================================+
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| WHAT IS DIVA STREAMING |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Diva streaming is one extension to Diva IDI interface which provides:
|
||||
Reduction of host load
|
||||
Reduction of delay and delay variance of data stream
|
||||
|
||||
This achieved by:
|
||||
Use of individual and independent logical BUS master DMA channel
|
||||
for every data stream (for every PLCI)
|
||||
Data transfer without copy operations and without system calls/context switches
|
||||
Available for user mode and for kernel mode applications
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| HOW TO ACTIVATE DIVA STREAMING SUPPORT IN CHAN_CAPI |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
To activate Diva streaming support in chan_capi please compile
|
||||
chan_capi with MAKE variable DIVA_STREAMING set to one:
|
||||
|
||||
make DIVA_STREAMING=1
|
||||
|
||||
and install new chan_capi module:
|
||||
|
||||
make install DIVA_STREAMING=1
|
||||
|
||||
chan_capi automatically detects if Diva streaming is supported by available Diva hardware.
|
||||
|
||||
You can disable use of Diva streaming at run time (without need to re-compile of chan_capi)
|
||||
if you set "nodivastreaming" variable in "[general]" section of "capi.conf" to one:
|
||||
|
||||
[general]
|
||||
nodivastreaming=1
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| PERFORMANCE METRICS ON CHAN_CAPI |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Hardware: 8 x 2.8GHz Xeon, 8GByte memory, Debian lenny 64Bit
|
||||
Diva hardware: Dialogic Diva V-8PRI PCIe FS v1
|
||||
Test: 240 channels GSM voice streaming
|
||||
|
||||
Voice transcoding by Asterisk and data exchange using CAPI:
|
||||
System load 50%
|
||||
Voice delay (additional): 20 mSec, delay variance 10mSec
|
||||
|
||||
Voice transcoding by Astrisk and data exchange using Diva streaming:
|
||||
System load 10%
|
||||
Voice delay (additional): 2 mSec, delay variance 1 mSec
|
||||
|
||||
Voice transcoding by Diva and data exchange using Diva streaming:
|
||||
System load 2%
|
||||
Voice delay (additional): 2 mSec, delay variance 1 mSec
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| SUPPORTED HARDWARE |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Diva streaming is supported by following hardware:
|
||||
Dialogic Diva V-4PRI/E1/T1-120 PCI v1
|
||||
Dialogic Diva 4PRI/E1/T1-120 PCI v1
|
||||
Dialogic Diva V-2PRI/E1/T1-60 PCI v1
|
||||
Dialogic Diva 2PRI/E1/T1-60 PCI v1
|
||||
Dialogic Diva V-4PRI PCIe HS v1
|
||||
Dialogic Diva V-2PRI PCIe HS v1
|
||||
Dialogic Diva V-1PRI PCIe HS v1
|
||||
Dialogic Diva V-4PRI PCIe FS v1
|
||||
Dialogic Diva V-8PRI PCIe FS v1
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
+===================================================================+
|
||||
| AMI commands and events |
|
||||
| |
|
||||
| Device state events |
|
||||
+===================================================================+
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Action CapichatList |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
List all users in conference or in all conferences
|
||||
|
||||
Conference: Capi chat room name
|
||||
|
||||
If Conference is not provided then command lists all users in all capi chat rooms.
|
||||
|
||||
List of users is delicered as serie of CapichatList events.
|
||||
List of users starts ends with CapichatListComplete event.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Action CapichatMute |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Mute all regular users if conference or mute selected user.
|
||||
|
||||
Conference: Conference room to mute
|
||||
Member: User to mute (Channel name)
|
||||
Path: Path to mute (Rx or Tx)
|
||||
|
||||
If only Conference provided then entire room is muted.
|
||||
If only Member provided then only selected user is muted.
|
||||
If Path not provided then Tx path is assumed.
|
||||
Path is valid only if Member iss provided.
|
||||
|
||||
If mute only one member this command is alias for capicommand
|
||||
txdgain,-128
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Action CapichatUnmute |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Mute all regular users if conference or mute selected user.
|
||||
|
||||
Conference: Conference room to unmute
|
||||
Member: User to mute (Channel name)
|
||||
Path: Path to mute (Rx or Tx)
|
||||
|
||||
If only Conference provided then entire room is muted.
|
||||
If only Member provided then only selected user is muted.
|
||||
If Path not provided then Tx path is assumed.
|
||||
Path is valid only if Member iss provided.
|
||||
|
||||
If unmute only one member this command is alias for capicommand
|
||||
txdgain,0
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Action CapichatRemove |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Remove member from conference
|
||||
|
||||
Conference: Conference room name
|
||||
Member: User to remove (Channel name)
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Action CapiCommand |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Execute any of supported capicommand commands (echocance,
|
||||
noisesuppressor, ...).
|
||||
|
||||
Channel: Channel name
|
||||
Command: capicomand command
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Event CapichatList |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Provided information about state of conference member.
|
||||
|
||||
Event: CapichatList
|
||||
ActionID: Action ID as used in CapichatList request.
|
||||
Conference: Conference room name
|
||||
UserNumber: User in conference
|
||||
CallerIDNum: CID
|
||||
CallerIDName: CID name
|
||||
Channel: Channel name
|
||||
Admin: Yes/No
|
||||
Role: Listen onlys/Talk and listen/Talk only
|
||||
MarkedUser: Yes/No
|
||||
Muted: No/By self/By admin/
|
||||
Talking: Yes/No/Not monitored
|
||||
Domain: TDM/IP
|
||||
DTMF: %s\r\n"
|
||||
EchoCancel: Yes/No
|
||||
NoiseSupp: Yes/No
|
||||
RxAGC: Yes/No
|
||||
TxAGC: Yes/No
|
||||
RxGain: Gain value in dB
|
||||
TxGain: Gain value in dB
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Event CapichatListComplet |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Terminates serie of CapichatList events.
|
||||
|
||||
ListItems: Mumber of CapichatList events preceeding to this event
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Event CapichatJoin |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
User joined conference
|
||||
|
||||
Channel: User name (Channel name)
|
||||
Uniqueid: Unique channel ID
|
||||
Conference: Conference room name
|
||||
Conferencenum: Conference room number
|
||||
CallerIDnum: CID
|
||||
CallerIDname: CID name
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Event CapichatLeave |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
User leaved conference
|
||||
|
||||
Channel: User name (Channel name)
|
||||
Uniqueid: Unique channel ID
|
||||
Conference: Conference room name
|
||||
Conferencenum: Conference room number
|
||||
CallerIDnum: CID
|
||||
CallerIDname: CID name
|
||||
Duration: Time user spend in conference, sec.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Event CapichatEnd |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Last user leaved conference
|
||||
|
||||
Conference: Conference room name
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Device state event ISDN/I[N]/congestion |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Device state event ISDN/I[N]/congestion, where [N] is CAPI controller
|
||||
number.
|
||||
Provides state of CAPI interface.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Device state event capichat:[room] |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Device state event capichat:[room], where [room] is the conference
|
||||
name.
|
||||
Provides state of Capichat conference room.
|
||||
|
347
README.media
347
README.media
|
@ -21,11 +21,11 @@ Supported hardware:
|
|||
feature only together with RTP.
|
||||
|
||||
Syntax:
|
||||
noisesuppressor|yes,no
|
||||
noisesuppressor,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(noisesuppressor|yes)
|
||||
s,n,capicommand(noisesuppressor|no)
|
||||
s,n,capicommand(noisesuppressor,yes)
|
||||
s,n,capicommand(noisesuppressor,no)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -36,9 +36,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(noisesuppressor|yes)
|
||||
exten => 1,1,capicommand(noisesuppressor,yes)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(noisesuppressor|no)
|
||||
exten => 2,1,capicommand(noisesuppressor,no)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -49,7 +49,7 @@ exten => h,1,Hangup
|
|||
PBX Example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[macro-capinoisesuppressor]
|
||||
exten => s,1,capicommand(noisesuppressor|yes)
|
||||
exten => s,1,capicommand(noisesuppressor,yes)
|
||||
|
||||
[isdn-in]
|
||||
exten => 12345,1,Progress()
|
||||
|
@ -58,7 +58,7 @@ exten => 12345,n,Set(TIMEOUT(response)=5) ; Set Response Timeout to 10 seconds
|
|||
exten => 12345,n,Playback(demo-enterkeywords,noanswer,us)
|
||||
exten => 12345,n,Answer
|
||||
exten => 12345,n,Wait(2)
|
||||
exten => 12345,n,capicommand(noisesuppressor|yes)
|
||||
exten => 12345,n,capicommand(noisesuppressor,yes)
|
||||
exten => 12345,n,Dial(DIALOGICDIVA/ISDN1/100,10,M(capinoisesuppressor))
|
||||
exten => 12345,n,Hangup()
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -79,14 +79,14 @@ Supported hardware:
|
|||
Requires one Dialogic(R) Diva(R) Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
clamping|N
|
||||
clamping,N
|
||||
N - estimated duration of DTMF tones to be suppressed in ms
|
||||
0 - deactivate clamping
|
||||
1 ... 250 - activate clamping
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(clamping|100)
|
||||
s,n,capicommand(clamping|0)
|
||||
s,n,capicommand(clamping,100)
|
||||
s,n,capicommand(clamping,0)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -97,9 +97,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(clamping|100)
|
||||
exten => 1,1,capicommand(clamping,100)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(clamping|0)
|
||||
exten => 2,1,capicommand(clamping,0)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -110,7 +110,7 @@ exten => h,1,Hangup
|
|||
PBX Example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[macro-capiclamping]
|
||||
exten => s,1,capicommand(clamping|100)
|
||||
exten => s,1,capicommand(clamping,100)
|
||||
|
||||
[isdn-in]
|
||||
exten => 12345,1,Progress()
|
||||
|
@ -119,7 +119,7 @@ exten => 12345,n,Set(TIMEOUT(response)=5) ; Set Response Timeout to 10 seconds
|
|||
exten => 12345,n,Playback(demo-enterkeywords,noanswer,us)
|
||||
exten => 12345,n,Answer
|
||||
exten => 12345,n,Wait(2)
|
||||
exten => 12345,n,capicommand(clamping|100)
|
||||
exten => 12345,n,capicommand(clamping,100)
|
||||
exten => 12345,n,Dial(DIALOGICDIVA/ISDN1/100,10,M(capiclamping))
|
||||
exten => 12345,n,Hangup()
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -140,11 +140,11 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
rxagc|yes,no
|
||||
rxagc,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(rxagc|yes)
|
||||
s,n,capicommand(rxagc|no)
|
||||
s,n,capicommand(rxagc,yes)
|
||||
s,n,capicommand(rxagc,no)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -155,9 +155,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(rxagc|yes)
|
||||
exten => 1,1,capicommand(rxagc,yes)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(rxagc|no)
|
||||
exten => 2,1,capicommand(rxagc,no)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -168,7 +168,7 @@ exten => h,1,Hangup
|
|||
PBX Example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[macro-capirxagc]
|
||||
exten => s,1,capicommand(rxagc|yes)
|
||||
exten => s,1,capicommand(rxagc,yes)
|
||||
|
||||
[isdn-in]
|
||||
exten => 12345,1,Progress()
|
||||
|
@ -177,7 +177,7 @@ exten => 12345,n,Set(TIMEOUT(response)=5) ; Set Response Timeout to 10 seconds
|
|||
exten => 12345,n,Playback(demo-enterkeywords,noanswer,us)
|
||||
exten => 12345,n,Answer
|
||||
exten => 12345,n,Wait(2)
|
||||
exten => 12345,n,capicommand(rxagc|yes)
|
||||
exten => 12345,n,capicommand(rxagc,yes)
|
||||
exten => 12345,n,Dial(DIALOGICDIVA/ISDN1/100,10,M(capirxagc))
|
||||
exten => 12345,n,Hangup()
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -198,11 +198,11 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
txagc|yes,no
|
||||
txagc,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(txagc|yes)
|
||||
s,n,capicommand(txagc|no)
|
||||
s,n,capicommand(txagc,yes)
|
||||
s,n,capicommand(txagc,no)
|
||||
|
||||
IVR example:
|
||||
See rxagc
|
||||
|
@ -226,14 +226,14 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
rxdgain|N
|
||||
rxdgain,N
|
||||
N - gain in dBm, float
|
||||
-127 ... +6 - gain
|
||||
-128 or less - infinite attenuation
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(rxdgain|5.5)
|
||||
s,n,capicommand(rxdgain|-14.2)
|
||||
s,n,capicommand(rxdgain,5.5)
|
||||
s,n,capicommand(rxdgain,-14.2)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -244,9 +244,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(rxdgain|5.5)
|
||||
exten => 1,1,capicommand(rxdgain,5.5)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(rxdgain|-70)
|
||||
exten => 2,1,capicommand(rxdgain,-70)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -270,12 +270,12 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
incSyntax:
|
||||
rxdgain|N
|
||||
rxdgain,N
|
||||
N - gain increment in dBm, float
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(incrxdgain|2.5) // add 2.5 dBm to actiall gain
|
||||
s,n,capicommand(incrxdgain|-2.5) // substract 2.5 dBm from actual gain
|
||||
s,n,capicommand(incrxdgain,2.5) // add 2.5 dBm to actiall gain
|
||||
s,n,capicommand(incrxdgain,-2.5) // substract 2.5 dBm from actual gain
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -286,9 +286,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(incrxdgain|2.5)
|
||||
exten => 1,1,capicommand(incrxdgain,2.5)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(incrxdgain|-2.5)
|
||||
exten => 2,1,capicommand(incrxdgain,-2.5)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -312,14 +312,14 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
txdgain|N
|
||||
txdgain,N
|
||||
N - gain in dBm, float
|
||||
-127 ... +6 - gain
|
||||
-128 or less - infinite attenuation
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(txdgain|5.5)
|
||||
s,n,capicommand(txdgain|-14.2)
|
||||
s,n,capicommand(txdgain,5.5)
|
||||
s,n,capicommand(txdgain,-14.2)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -330,9 +330,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(txdgain|5.5)
|
||||
exten => 1,1,capicommand(txdgain,5.5)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(txdgain|-70)
|
||||
exten => 2,1,capicommand(txdgain,-70)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -356,12 +356,12 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
incSyntax:
|
||||
rxtgain|N
|
||||
rxtgain,N
|
||||
N - gain increment in dBm, float
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(inctxdgain|2.5) // add 2.5 dBm to actiall gain
|
||||
s,n,capicommand(inctxdgain|-2.5) // substract 2.5 dBm from actual gain
|
||||
s,n,capicommand(inctxdgain,2.5) // add 2.5 dBm to actiall gain
|
||||
s,n,capicommand(inctxdgain,-2.5) // substract 2.5 dBm from actual gain
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -372,9 +372,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(inctxdgain|2.5)
|
||||
exten => 1,1,capicommand(inctxdgain,2.5)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(inctxdgain|-2.5)
|
||||
exten => 2,1,capicommand(inctxdgain,-2.5)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -404,15 +404,15 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
pitchcontrol|RxN|TxN - set Rx and Tx rate to different values
|
||||
pitchcontrol|N - set Rx and Tx rate to same value
|
||||
pitchcontrol,RxN,TxN - set Rx and Tx rate to different values
|
||||
pitchcontrol,N - set Rx and Tx rate to same value
|
||||
pitchcontrol - deactivate rate control
|
||||
|
||||
RxN, TxN, N - rate in the range 1250 ... 51200 Hz.
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(pitchcontrol|8200,8100) ; Set Rx rate to 8200 Hz and Tx rate to 8100 Hz
|
||||
s,n,capicommand(pitchcontrol|8400) ; Set Rx and Tx rate to 8400 Hz
|
||||
s,n,capicommand(pitchcontrol,8200,8100) ; Set Rx rate to 8200 Hz and Tx rate to 8100 Hz
|
||||
s,n,capicommand(pitchcontrol,8400) ; Set Rx and Tx rate to 8400 Hz
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -423,9 +423,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(pitchcontrol|8200)
|
||||
exten => 1,1,capicommand(pitchcontrol,8200)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(pitchcontrol|8000)
|
||||
exten => 2,1,capicommand(pitchcontrol,8000)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -455,14 +455,14 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
incpitchcontrol|RxN|TxN - change Rx and Tx rate using different values
|
||||
incpitchcontrol|N - change Rx and Tx rate using same value
|
||||
incpitchcontrol,RxN,TxN - change Rx and Tx rate using different values
|
||||
incpitchcontrol,N - change Rx and Tx rate using same value
|
||||
|
||||
RxN, TxN, N - rate change in Hz
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(incpitchcontrol|100) // Increase Rx and Tx rate by 100 Hz
|
||||
s,n,capicommand(incpitchcontrol|-100) // Decrease Rx and Tx rate by 100 Hz
|
||||
s,n,capicommand(incpitchcontrol,100) // Increase Rx and Tx rate by 100 Hz
|
||||
s,n,capicommand(incpitchcontrol,-100) // Decrease Rx and Tx rate by 100 Hz
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -473,9 +473,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(incpitchcontrol|100)
|
||||
exten => 1,1,capicommand(incpitchcontrol,100)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(incpitchcontrol|100)
|
||||
exten => 2,1,capicommand(incpitchcontrol,100)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -501,11 +501,11 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
mftonedetection|yes,no
|
||||
mftonedetection,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(mftonedetection|yes)
|
||||
s,n,capicommand(mftonedetection|no)
|
||||
s,n,capicommand(mftonedetection,yes)
|
||||
s,n,capicommand(mftonedetection,no)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -516,9 +516,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(mftonedetection|yes)
|
||||
exten => 1,1,capicommand(mftonedetection,yes)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(mftonedetection|no)
|
||||
exten => 2,1,capicommand(mftonedetection,no)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -542,11 +542,11 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
pulsedetection|yes,no
|
||||
pulsedetection,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(pulsedetection|yes)
|
||||
s,n,capicommand(pulsedetection|no)
|
||||
s,n,capicommand(pulsedetection,yes)
|
||||
s,n,capicommand(pulsedetection,no)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -557,9 +557,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(pulsedetection|yes)
|
||||
exten => 1,1,capicommand(pulsedetection,yes)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(pulsedetection|no)
|
||||
exten => 2,1,capicommand(pulsedetection,no)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -584,7 +584,7 @@ Supported hardware:
|
|||
Requires one Diva Media Board equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
sendtone|N
|
||||
sendtone,N
|
||||
stoptone
|
||||
|
||||
N - tone to be sent
|
||||
|
@ -633,7 +633,7 @@ stoptone
|
|||
0xCB - Tone Alerting Signal (for Caller ID in PSTN)
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(sendtone|0x83) ; Send PABX internal dial tone
|
||||
s,n,capicommand(sendtone,0x83) ; Send PABX internal dial tone
|
||||
s,n,capicommand(stoptone) ; stop tone transmission
|
||||
|
||||
IVR example
|
||||
|
@ -645,7 +645,7 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(sendtone|0x83)
|
||||
exten => 1,1,capicommand(sendtone,0x83)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(stoptone)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
|
@ -673,7 +673,7 @@ Supported hardware:
|
|||
Not available if RTP is active.
|
||||
|
||||
Syntax:
|
||||
starttonedetection|N
|
||||
starttonedetection,N
|
||||
stoptonedetection
|
||||
|
||||
N - Extension number to be used in case a tone is detected.
|
||||
|
@ -729,7 +729,7 @@ stoptonedetection
|
|||
0xCB - Tone Alerting Signal detected (for Caller ID in PSTN)
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(starttonedetection|98) ; Change to extension 98 after detection of tone
|
||||
s,n,capicommand(starttonedetection,98) ; Change to extension 98 after detection of tone
|
||||
s,n,capicommand(stoptonedetection) ; Disable detection of tones
|
||||
|
||||
IVR example:
|
||||
|
@ -746,7 +746,7 @@ exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
|||
|
||||
exten => 1,1,Set(TIMEOUT(digit)=1)
|
||||
exten => 1,n,Set(TIMEOUT(response)=5)
|
||||
exten => 1,n,capicommand(starttonedetection|98) ; Change to 98 once tone is detected
|
||||
exten => 1,n,capicommand(starttonedetection,98) ; Change to 98 once tone is detected
|
||||
exten => 1,n,Goto(s,restart)
|
||||
|
||||
; Continue after detection of the tone
|
||||
|
@ -786,13 +786,13 @@ Description:
|
|||
independent from the dialplan.
|
||||
|
||||
Syntax:
|
||||
vc|command|key|param|param1|...|paranN
|
||||
Add to menu: on detection of key execute command using parameters param1|...|paramN
|
||||
vc,command,key,param,param1,...,paranN
|
||||
Add to menu: on detection of key execute command using parameters param1,...,paramN
|
||||
|
||||
vc|command|key
|
||||
vc,command,key
|
||||
Add to menu: on detection of key execute command without parameters
|
||||
|
||||
vc|command
|
||||
vc,command
|
||||
Remove all instances of command from menu
|
||||
|
||||
vc
|
||||
|
@ -800,12 +800,12 @@ vc
|
|||
|
||||
In case one command will use a key that is already in use, then a new command will overwrite
|
||||
the existing command:
|
||||
exten => s,n,capicommand(vc|txagc|3|yes)
|
||||
exten => s,n,capicommand(vc|inctxdgain|3|1.5)
|
||||
exten => s,n,capicommand(vc,txagc,3,yes)
|
||||
exten => s,n,capicommand(vc,inctxdgain,3,1.5)
|
||||
|
||||
is equivalent to:
|
||||
|
||||
exten => s,n,capicommand(vc|inctxdgain|3|1.5)
|
||||
exten => s,n,capicommand(vc,inctxdgain,3,1.5)
|
||||
|
||||
It is better to use only one digit as key for commands in menu if using the menu for IVR and
|
||||
voice mailbox. This provides short response time.
|
||||
|
@ -814,8 +814,8 @@ In case the menu is used for conference or for connection between two parties, i
|
|||
two or three digits for the key. This will prevent an activation by accidentally pressing a key.
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(vc|inctxdgain|5|1.5) ; Execute inctxdgain|1.5 if received DTMF digit 5
|
||||
exten => s,n,capicommand(vc|txagc|3|yes) ; Execute txagc|yes if received DTMF digit 3
|
||||
exten => s,n,capicommand(vc,inctxdgain,5,1.5) ; Execute inctxdgain,1.5 if received DTMF digit 5
|
||||
exten => s,n,capicommand(vc,txagc,3,yes) ; Execute txagc,yes if received DTMF digit 3
|
||||
|
||||
IVR Example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -823,14 +823,14 @@ IVR Example:
|
|||
exten => _X.,1,Answer
|
||||
exten => _X.,n,Goto(s,1)
|
||||
exten => s,1,Wait(1)
|
||||
exten => s,n,capicommand(vc|sendtone|1|0x82)
|
||||
exten => s,n,capicommand(vc|stoptone|2)
|
||||
exten => s,n,capicommand(vc|txagc|3|yes)
|
||||
exten => s,n,capicommand(vc|txagc|4|no)
|
||||
exten => s,n,capicommand(vc|inctxdgain|5|1.5)
|
||||
exten => s,n,capicommand(vc|inctxdgain|7|-2.5)
|
||||
exten => s,n,capicommand(vc|incpitchcontrol|8|0|100)
|
||||
exten => s,n,capicommand(vc|incpitchcontrol|9|0|-400)
|
||||
exten => s,n,capicommand(vc,sendtone,1,0x82)
|
||||
exten => s,n,capicommand(vc,stoptone,2)
|
||||
exten => s,n,capicommand(vc,txagc,3,yes)
|
||||
exten => s,n,capicommand(vc,txagc,4,no)
|
||||
exten => s,n,capicommand(vc,inctxdgain,5,1.5)
|
||||
exten => s,n,capicommand(vc,inctxdgain,7,-2.5)
|
||||
exten => s,n,capicommand(vc,incpitchcontrol,8,0,100)
|
||||
exten => s,n,capicommand(vc,incpitchcontrol,9,0,-400)
|
||||
exten => s,n(restart),Playback(demo-instruct)
|
||||
exten => s,n,Goto(s,restart)
|
||||
exten => s,n,Hangup
|
||||
|
@ -870,7 +870,7 @@ Supported hardware:
|
|||
Diva
|
||||
|
||||
Syntax:
|
||||
capicommand(chat|<roomname>|<options>|controller)
|
||||
capicommand(chat,<roomname>,<options>,controller)
|
||||
roomname - conference room name
|
||||
options
|
||||
m - The first caller will get music-on-hold until the second caller arrives
|
||||
|
@ -880,12 +880,12 @@ capicommand(chat|<roomname>|<options>|controller)
|
|||
controller - CAPI controller
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(chat|test|m|1)
|
||||
exten => s,n,capicommand(chat|test|m|1,3)
|
||||
exten => s,n,capicommand(chat|test|m|1-4)
|
||||
exten => s,n,capicommand(chat|test|m|1-4,7)
|
||||
exten => s,n,capicommand(chat|test|m|1-4,7-10)
|
||||
exten => s,n,capicommand(chat|test|mh300|1-4)
|
||||
exten => s,n,capicommand(chat,test,m,1)
|
||||
exten => s,n,capicommand(chat,test,m,1,3)
|
||||
exten => s,n,capicommand(chat,test,m,1-4)
|
||||
exten => s,n,capicommand(chat,test,m,1-4,7)
|
||||
exten => s,n,capicommand(chat,test,m,1-4,7-10)
|
||||
exten => s,n,capicommand(chat,test,mh300,1-4)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -898,21 +898,21 @@ exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
|||
exten => s,n,WaitExten ; Wait for an extension to be dialed, use to select conference room
|
||||
|
||||
; You can create macro to set up vc menu
|
||||
exten => 1,1,capicommand(clamping|100) ; Activate suppression of DTMF tones
|
||||
exten => 1,n,capicommand(vc|incrxdgain|0|1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => 1,n,capicommand(vc|incrxdgain|1|-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => 1,n,capicommand(vc|txdgain|2|-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => 1,n,capicommand(vc|txdgain|3|0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => 1,n,capicommand(chat|test1|m|1-4) ; Create/enter conference room 'test1'
|
||||
exten => 1,1,capicommand(clamping,100) ; Activate suppression of DTMF tones
|
||||
exten => 1,n,capicommand(vc,incrxdgain,0,1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => 1,n,capicommand(vc,incrxdgain,1,-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => 1,n,capicommand(vc,txdgain,2,-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => 1,n,capicommand(vc,txdgain,3,0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => 1,n,capicommand(chat,test1,m,1-4) ; Create/enter conference room 'test1'
|
||||
|
||||
exten => 2,1,capicommand(clamping|100) ; Activate suppression of DTMF tones
|
||||
exten => 2,n,capicommand(txdgain|-128) ; Deactivate tx path
|
||||
exten => 2,n,capicommand(vc|incrxdgain|0|1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => 2,n,capicommand(vc|incrxdgain|1|-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => 2,n,capicommand(vc|txdgain|2|-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => 2,n,capicommand(vc|txdgain|3|0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => 2,n,capicommand(chat|test1|m|1-4) ; Create/enter conference room 'test1
|
||||
exten => 2,n,capicommand(chat|test2|m|1-4) ; Create/enter conference room 'test2'
|
||||
exten => 2,1,capicommand(clamping,100) ; Activate suppression of DTMF tones
|
||||
exten => 2,n,capicommand(txdgain,-128) ; Deactivate tx path
|
||||
exten => 2,n,capicommand(vc,incrxdgain,0,1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => 2,n,capicommand(vc,incrxdgain,1,-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => 2,n,capicommand(vc,txdgain,2,-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => 2,n,capicommand(vc,txdgain,3,0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => 2,n,capicommand(chat,test1,m,1-4) ; Create/enter conference room 'test1
|
||||
exten => 2,n,capicommand(chat,test2,m,1-4) ; Create/enter conference room 'test2'
|
||||
|
||||
exten => i,1,Playback(invalid)
|
||||
exten => i,n,Goto(s,restart)
|
||||
|
@ -1006,32 +1006,35 @@ Supported hardware:
|
|||
|
||||
|
||||
Syntax:
|
||||
capicommand(ressource|controller)
|
||||
capicommand(ressource,controller[,codeclist])
|
||||
controller - CAPI controller
|
||||
|
||||
codeclist - separated by '+' character list of supported codecs, optional
|
||||
codec oder codec1+codec2+...+codecN
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(resource|1)
|
||||
exten => s,n,capicommand(resource|1,3)
|
||||
exten => s,n,capicommand(resource|1-4)
|
||||
exten => s,n,capicommand(resource|1-4,7)
|
||||
exten => s,n,capicommand(resource|1-4,7-10)
|
||||
exten => s,n,capicommand(resource,1)
|
||||
exten => s,n,capicommand(resource,1,3)
|
||||
exten => s,n,capicommand(resource,1-4)
|
||||
exten => s,n,capicommand(resource,1-4,7)
|
||||
exten => s,n,capicommand(resource,1-4,7-10)
|
||||
exten => s,n,capicommand(resource,1-4,7-10,gsm)
|
||||
exten => s,n,capicommand(resource,1-4,7-10,alaw+ulaw+gsm+g722)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[isdn-in]
|
||||
exten => _X.,1,Answer ; Answer the line
|
||||
exten => _X.,n,Goto(s,1)
|
||||
exten => s,1,capicommand(resource|1-4) ; Create DSP resource on CAPI controllers 1-4 for IP members,
|
||||
exten => s,1,capicommand(resource,1-4) ; Create DSP resource on CAPI controllers 1-4 for IP members,
|
||||
; ignore command for E.1/T.1/S0/POTS members
|
||||
exten => s,n,capicommand(clamping|100) ; Activate suppression of DTMF tones
|
||||
exten => s,n,capicommand(rxagc|yes) ; Activate Rx AGC
|
||||
exten => s,n,capicommand(noisesuppressor|yes) ; Activate suppression of ambient noises
|
||||
exten => s,n,capicommand(vc|incrxdgain|0|1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => s,n,capicommand(vc|incrxdgain|1|-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => s,n,capicommand(vc|txdgain|2|-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => s,n,capicommand(vc|txdgain|3|0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => s,n,capicommand(chat|test1|m|1-4) ; Craete/enter conference toom 'test1', controller field is ignored if
|
||||
exten => s,n,capicommand(clamping,100) ; Activate suppression of DTMF tones
|
||||
exten => s,n,capicommand(rxagc,yes) ; Activate Rx AGC
|
||||
exten => s,n,capicommand(noisesuppressor,yes) ; Activate suppression of ambient noises
|
||||
exten => s,n,capicommand(vc,incrxdgain,0,1.5) ; Install voice command menu for volume control, '0' to increase volume
|
||||
exten => s,n,capicommand(vc,incrxdgain,1,-1.5) ; Install voice command menu for volume control, '1' to decrease volume
|
||||
exten => s,n,capicommand(vc,txdgain,2,-128) ; Install voice command menu for volume control, '2' to mute tx path
|
||||
exten => s,n,capicommand(vc,txdgain,3,0) ; Install voice command menu for volume control, '3' to activate tx path
|
||||
exten => s,n,capicommand(chat,test1,m,1-4) ; Craete/enter conference toom 'test1', controller field is ignored if
|
||||
; media processing resource is assigned by 'resource' command or for
|
||||
; E.1/T.1/S0/POTS members
|
||||
|
||||
|
@ -1071,14 +1074,14 @@ Direction:
|
|||
|
||||
Note:
|
||||
The voice stream of regular users is active by default. If the conference mode was changed to half duplex
|
||||
('chat_mute|yes'), then new regular users are created with a deactivated voice stream until the conference
|
||||
mode is changed back to full duplex ('chat_mute|no')
|
||||
('chat_mute,yes'), then new regular users are created with a deactivated voice stream until the conference
|
||||
mode is changed back to full duplex ('chat_mute,no')
|
||||
|
||||
Supported hardware:
|
||||
Diva
|
||||
|
||||
Syntax:
|
||||
capicommand(chat_mute|<action>[|<roomname>])
|
||||
capicommand(chat_mute,<action>[,<roomname>])
|
||||
action - mandatory
|
||||
yes - Change conference mode to half duplex, deactivate voice stream from regular
|
||||
users to conference.
|
||||
|
@ -1090,32 +1093,32 @@ capicommand(chat_mute|<action>[|<roomname>])
|
|||
functionality of a common conference operator.
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(chat_mute|yes)
|
||||
exten => s,n,capicommand(char_mute|no)
|
||||
exten => s,n,capicommand(chat_mute|yes|test_room)
|
||||
exten => s,n,capicommand(char_mute|no|test_room)
|
||||
exten => s,n,capicommand(chat_mute,yes)
|
||||
exten => s,n,capicommand(char_mute,no)
|
||||
exten => s,n,capicommand(chat_mute,yes,test_room)
|
||||
exten => s,n,capicommand(char_mute,no,test_room)
|
||||
|
||||
Conference example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[isdn-in]
|
||||
exten => 1291,1,Answer ; Accept call
|
||||
exten => 1291,n,capicommand(resource|1-4) ; assign resource PLCI if call from IP
|
||||
exten => 1291,n,capicommand(clamping|200) ; Activate DTMF suppression
|
||||
exten => 1291,n,capicommand(vc|chat_mute|0|yes) ; Voice command, key 0 - change to half duplex mode
|
||||
exten => 1291,n,capicommand(vc|chat_mute|1|no) ; Voice command, key 0 - change to full duplex mode
|
||||
exten => 1291,n,capicommand(chat|test_chat|mo|1-4) ; Add to conference as operator
|
||||
exten => 1291,n,capicommand(resource,1-4) ; assign resource PLCI if call from IP
|
||||
exten => 1291,n,capicommand(clamping,200) ; Activate DTMF suppression
|
||||
exten => 1291,n,capicommand(vc,chat_mute,0,yes) ; Voice command, key 0 - change to half duplex mode
|
||||
exten => 1291,n,capicommand(vc,chat_mute,1,no) ; Voice command, key 0 - change to full duplex mode
|
||||
exten => 1291,n,capicommand(chat,test_chat,mo,1-4) ; Add to conference as operator
|
||||
exten => 1291,n,Hangup()
|
||||
|
||||
exten => 1292,1,Answer ; Accept call
|
||||
exten => 1292,n,capicommand(resource|1-4) ; Assign resource PLCI if call from IP
|
||||
exten => 1292,n,capicommand(clamping|200) ; Activate DTMF suppression
|
||||
exten => 1292,n,capicommand(chat|test_chat|m|1-4) ; Add to conference as regular user
|
||||
exten => 1292,n,capicommand(resource,1-4) ; Assign resource PLCI if call from IP
|
||||
exten => 1292,n,capicommand(clamping,200) ; Activate DTMF suppression
|
||||
exten => 1292,n,capicommand(chat,test_chat,m,1-4) ; Add to conference as regular user
|
||||
exten => 1292,n,Hangup()
|
||||
|
||||
exten => 1293,1,Answer ; Accept call
|
||||
exten => 1293,n,capicommand(resource|1-4) ; Assign resource PLCI if call from IP
|
||||
exten => 1293,n,capicommand(clamping|200) ; Activate DTMF suppression
|
||||
exten => 1293,n,capicommand(chat|test_chat|ml|1-4) ; Add to conference as listener
|
||||
exten => 1293,n,capicommand(resource,1-4) ; Assign resource PLCI if call from IP
|
||||
exten => 1293,n,capicommand(clamping,200) ; Activate DTMF suppression
|
||||
exten => 1293,n,capicommand(chat,test_chat,ml,1-4) ; Add to conference as listener
|
||||
exten => 1293,n,Hangup()
|
||||
|
||||
exten => _X.,1,Answer
|
||||
|
@ -1142,7 +1145,7 @@ Supported hardware:
|
|||
Diva
|
||||
|
||||
Syntax:
|
||||
capicommand(chat_play|<roomname>|<options>|<filename>|controller)
|
||||
capicommand(chat_play,<roomname>,<options>,<filename>,controller)
|
||||
roomname - conference room name
|
||||
options
|
||||
m - The caller will get music-on-hold while message is played
|
||||
|
@ -1151,22 +1154,22 @@ capicommand(chat_play|<roomname>|<options>|<filename>|controller)
|
|||
controller - CAPI controller
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(chat|test|m|/tmp/file.alaw|1)
|
||||
exten => s,n,capicommand(chat|test||/tmp/file.alaw|1-4,7-10)
|
||||
exten => s,n,capicommand(chat,test,m,/tmp/file.alaw,1)
|
||||
exten => s,n,capicommand(chat,test,,/tmp/file.alaw,1-4,7-10)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[isdn-in]
|
||||
exten => _X.,1,Answer ; Answer the line
|
||||
exten => _X.,n,Goto(s,1)
|
||||
exten => s,1,capicommand(clamping|100) ; Activate suppression of DTMF tones
|
||||
exten => s,1,capicommand(clamping,100) ; Activate suppression of DTMF tones
|
||||
exten => s,n,Playback(record-name) ; Ask for name
|
||||
exten => s,n,capicommand(rxagc|yes) ; Activate Rx AGC
|
||||
exten => s,n,capicommand(rxagc,yes) ; Activate Rx AGC
|
||||
exten => s,n,Record(/tmp/${UNIQUEID}-info:alaw) ; Record message
|
||||
exten => s,n,capicommand(rxagc|no) ; Deactivate Rx AGC
|
||||
exten => s,n,capicommand(chat_play|test|m|/tmp/${UNIQUEID}-info.alaw|1-4) ; Play message to conference,
|
||||
exten => s,n,capicommand(rxagc,no) ; Deactivate Rx AGC
|
||||
exten => s,n,capicommand(chat_play,test,m,/tmp/${UNIQUEID}-info.alaw,1-4) ; Play message to conference,
|
||||
; play music on hold to caller
|
||||
exten => s,n,capicommand(chat|test|m|1-4) ; Create/enter conference room 'test'
|
||||
exten => s,n,capicommand(chat,test,m,1-4) ; Create/enter conference room 'test'
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1181,7 +1184,7 @@ Supported hardware:
|
|||
Diva
|
||||
|
||||
Syntax:
|
||||
capicommand(chat_command|<options>|<roomname>)
|
||||
capicommand(chat_command,<options>,<roomname>)
|
||||
options - mandatory
|
||||
r - Remove newest user from conference.
|
||||
Command does not apply to calling member and be used by operators only.
|
||||
|
@ -1194,9 +1197,9 @@ capicommand(chat_command|<options>|<roomname>)
|
|||
roomname - optional, room caller assigned to is used if not present
|
||||
|
||||
Syntax example:
|
||||
exten => s,n,capicommand(chat_command|r)
|
||||
exten => s,n,capicommand(chat_command|lo|test)
|
||||
exten => s,n,capicommand(chat_command|a|test)
|
||||
exten => s,n,capicommand(chat_command,r)
|
||||
exten => s,n,capicommand(chat_command,lo,test)
|
||||
exten => s,n,capicommand(chat_command,a,test)
|
||||
|
||||
Conference example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -1205,15 +1208,15 @@ exten => _X.,1,Answer
|
|||
exten => _X.,n,Authenticate(12345)
|
||||
exten => _X.,n,Playback(vm-rec-name)
|
||||
exten => _X.,n,Record(/tmp/name${UNIQUEID}.alaw,5,15) ; Record name
|
||||
exten => _X.,n,capicommand(chat_play|c1||/tmp/name${UNIQUEID}.alaw|1-4) ; Play name to conference
|
||||
exten => _X.,n,capicommand(resource|1-4) ; Create resource PLCI if call from IP
|
||||
exten => _X.,n,capicommand(clamping|200) ; Activate suppression of DTMF codes
|
||||
exten => _X.,n,capicommand(vc|chat_mute|1|yes) ; Voice command, key 1 - mute all members except operators
|
||||
exten => _X.,n,capicommand(vc|chat_mute|2|no) ; Voice command, key 2 - unmute all members except operators
|
||||
exten => _X.,n,capicommand(vc|chat_command|0|a|c1) ; Voice command, key 0 - remove all members from conference
|
||||
exten => _X.,n,capicommand(vc|noisesuppressor|3|yes) ; Voice command, key 3 - turn noise suppression on
|
||||
exten => _X.,n,capicommand(vc|noisesuppressor|4|no) ; Voice command, key 4 - turn noise suppression off
|
||||
exten => _X.,n,capicommand(chat|c1|mo|1-4) ; Add caller to conference as operator
|
||||
exten => _X.,n,capicommand(chat_play,c1,,/tmp/name${UNIQUEID}.alaw,1-4) ; Play name to conference
|
||||
exten => _X.,n,capicommand(resource,1-4) ; Create resource PLCI if call from IP
|
||||
exten => _X.,n,capicommand(clamping,200) ; Activate suppression of DTMF codes
|
||||
exten => _X.,n,capicommand(vc,chat_mute,1,yes) ; Voice command, key 1 - mute all members except operators
|
||||
exten => _X.,n,capicommand(vc,chat_mute,2,no) ; Voice command, key 2 - unmute all members except operators
|
||||
exten => _X.,n,capicommand(vc,chat_command,0,a,c1) ; Voice command, key 0 - remove all members from conference
|
||||
exten => _X.,n,capicommand(vc,noisesuppressor,3,yes) ; Voice command, key 3 - turn noise suppression on
|
||||
exten => _X.,n,capicommand(vc,noisesuppressor,4,no) ; Voice command, key 4 - turn noise suppression off
|
||||
exten => _X.,n,capicommand(chat,c1,mo,1-4) ; Add caller to conference as operator
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1253,11 +1256,11 @@ Supported hardware:
|
|||
Diva Media Boards equipped with DSPs.
|
||||
|
||||
Syntax:
|
||||
echocancel|yes,no
|
||||
echocancel,[yes|no]
|
||||
|
||||
Syntax example:
|
||||
s,n,capicommand(echocancel|yes)
|
||||
s,n,capicommand(echocancel|no)
|
||||
s,n,capicommand(echocancel,yes)
|
||||
s,n,capicommand(echocancel,no)
|
||||
|
||||
IVR example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -1268,9 +1271,9 @@ exten => s,1,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
|
|||
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
|
||||
exten => s,n(restart),BackGround(demo-instruct) ; Play some instructions
|
||||
exten => s,n,WaitExten ; Wait for an extension to be dialed.
|
||||
exten => 1,1,capicommand(echocancel|yes)
|
||||
exten => 1,1,capicommand(echocancel,yes)
|
||||
exten => 1,n,Goto(s,restart)
|
||||
exten => 2,1,capicommand(echocancel|no)
|
||||
exten => 2,1,capicommand(echocancel,no)
|
||||
exten => 2,n,Goto(s,restart)
|
||||
exten => 99,1,Echo
|
||||
exten => i,1,Playback(invalid)
|
||||
|
@ -1281,13 +1284,13 @@ exten => h,1,Hangup
|
|||
PBX Example:
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
[macro-capiechocancel]
|
||||
exten => s,1,capicommand(echocancel|yes)
|
||||
exten => s,1,capicommand(echocancel,yes)
|
||||
|
||||
[isdn-in]
|
||||
exten => 12345,1,Progress()
|
||||
exten => 12345,n,Set(TIMEOUT(digit)=1) ; Set Digit Timeout to 5 seconds
|
||||
exten => 12345,n,Set(TIMEOUT(response)=5) ; Set Response Timeout to 10 seconds
|
||||
exten => 12345,n,capicommand(echocancel|yes)
|
||||
exten => 12345,n,capicommand(echocancel,yes)
|
||||
exten => 12345,n,Playback(demo-enterkeywords,noanswer,us)
|
||||
exten => 12345,n,Answer
|
||||
exten => 12345,n,Wait(2)
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
+===================================================================+
|
||||
| Message Waiting Indication (MWI) |
|
||||
+===================================================================+
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Control MWI indicators (MWI Server) |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Using Asterisk 1.6 or newer it is possible to provide information about state of user
|
||||
mailbox to ISDN phone.
|
||||
Dependent on the state of mailbox this is possible to send MWI Activate or MWI deactivate
|
||||
request to activate or to deactivate Message Waiting Indicator on the phone.
|
||||
|
||||
To activate MWI function on CAPI controller please provide in the configuration of this
|
||||
controller the list of mailboxes to be monitored:
|
||||
|
||||
mwimailbox=mailbox1[:controlling user number1[:controlling user provided number1]][@context1], ...
|
||||
|
||||
The use of parameters can differ from PBX to PBX and even from PBX installation to PBX installation.
|
||||
Following description apply to common use of parameters.
|
||||
|
||||
Where:
|
||||
mailbox - Number of mailbox. Used to subsscribe to mailbox (voicemail.conf
|
||||
and at same time used by PBX to address the MWI indicator on device.
|
||||
controlling user number - Number where mailbox can be accessed (often same as mailbox)
|
||||
controlling user provided number - Password, used by PBX to check permissions
|
||||
|
||||
Additional configuration parameters depends on type of PBX used and on the PBX installation:
|
||||
mwifacptynrtype - type of MWI facility party number, 0 - unknown (default), 1 - public
|
||||
mwifacptynrton - MWI facility party number type of number and numbering plan identification
|
||||
(coding as for byte 0 of the calling party number). This byte is only valid
|
||||
if byte mwifacptynrtype contains the value 1. Set to 0 by default.
|
||||
mwifacptynrpres - MWI facility party number type presentation and screening indicator
|
||||
(coding as for byte 1 of the calling party number). This byte is only valid
|
||||
if byte mwifacptynrtype contains the value 1. Setr to 0 by default.
|
||||
mwibasicservice - MWI basic Service, coded in accordance with ETS 300 196 [D.5]. Set to 1 (voice)
|
||||
by default.
|
||||
mwiinvocation - MWI invocation mode, 0 - deffered, 1 - immediate, 2 - combined,
|
||||
65535 - suppres invocation code. Set to 2 by default.
|
||||
|
||||
Example:
|
||||
|
||||
[ISDN1]
|
||||
controller=1
|
||||
mwimailbox=12345:12345:221122@other,12347:12348,12349
|
||||
|
||||
activates monitoring of the mailboxes: 12345@other, 12347@default and 12349@default and sending
|
||||
of MWI requests using CAPI controller 1.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Direct control MWI indicators (MWI Server) |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
This is possible to send MWI Activate and MWI deactivate messages
|
||||
directly from dialplan using capicommand(mwi, ...).
|
||||
This can be necessary if testing the system, if voice mailbox is managed
|
||||
by other software (not by asterisk) or to verify MWI parameters.
|
||||
|
||||
capicommand(mwi,xmit,activate, ...) where parameters are:
|
||||
CAPI controller, MWI basic service,Number Of Messages, Message Status, Message Reference, Invocation Mode,
|
||||
Facility Number Type, Type of Number, Presentation and Screening,Mailbox,
|
||||
Facility Number Type, Type of Number, Presentation and Screening, Controlling User Number,
|
||||
Facility Number Type, Type of Number, Presentaation and Screening, Controlling User Provided Number
|
||||
|
||||
capicommand(mwi,xmit,deactivate, ...) where parameters are:
|
||||
CAPI controller, MWI basic service, Invocation Mode,
|
||||
Facility Number Type, Type of Number, Presentation and Screening,Mailbox,
|
||||
Facility Number Type, Type of Number, Presentation and Screening, Controlling User Number
|
||||
|
||||
Example:
|
||||
exten => _X.,n,capicommand(mwi,xmit,activate,1|1|1|0|0|2|1|0|0|42|1|0|0|41||||)
|
||||
exten => _X.,n,capicommand(mwi,xmit,deactivate|1|1|2|1|0|0|41|1|0|0|41)
|
||||
|
||||
Please refer to COMMON-ISDN-API Version 2.0 Part III Supplementary Services for more details
|
||||
on parameters.
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Receive MWI messages (MWI Client) |
|
||||
+-------------------------------------------------------------------+
|
||||
|
||||
Upon reception of MWI Activate messages from network chan_capi automatically
|
||||
generates Asterisk MWI events for mailbox N@CAPI_Remote, where N is the
|
||||
received as part of MWI Activate message Calling Party Number.
|
||||
|
||||
|
||||
+-------------------------------------------------------------------+
|
||||
| Notes |
|
||||
+-------------------------------------------------------------------+
|
||||
PBX often use one separate BRI trunk for transferring of MWI information (only MWI requests are transmitted
|
||||
this trunk).
|
||||
|
||||
Certain PBX require up to 15 seconds until MWI information is processed.
|
||||
|
|
@ -58,7 +58,7 @@ The QSIG support includes:
|
|||
its subchannels
|
||||
|
||||
- Simple Call Transfer
|
||||
With capicommand(qsig_ct|src-id|dst-id), you can transfer an inbound call back to the qsig switch.
|
||||
With capicommand(qsig_ct,src-id,dst-id), you can transfer an inbound call back to the qsig switch.
|
||||
The B-channel of this call will be relased, so that the line is free for a next call.
|
||||
Unfortunately, the call will be completely released by the switch if the target is busy.
|
||||
If you need to know whether your target is busy, you can use the call transfer feature below.
|
||||
|
|
21
capi.conf
21
capi.conf
|
@ -41,6 +41,8 @@ faxdetect=off ;enable faxdetection and redirection to EXTEN 'fax' for incomin
|
|||
;outgoing calls. (default='off', possible values: 'incoming','outgoing','both')
|
||||
faxdetecttime=0 ;Only detect faxes during the first 'n' seconds of the call.
|
||||
;(default '0' meaning for the whole duration of the call)
|
||||
faxdestination=custom-fax,fax,1 ;Set custom context, exten and priority to jump to on faxdetect.
|
||||
;Default is "<current-context>,fax,1".
|
||||
accountcode= ;PBX accountcode to use in CDRs
|
||||
;amaflags=default;AMA flags for CDR ('default', 'omit', 'billing', or 'documentation')
|
||||
context=isdn-in ;context for incoming calls
|
||||
|
@ -76,4 +78,23 @@ devices=2 ;number of concurrent calls (B-Channels) on this controller
|
|||
;mohinterpret=default ;Asterisk 1.4: default music on hold class when placed on hold.
|
||||
;qsig=1 ;enable use of Q.SIG extensions. ECMA Variant
|
||||
;qsig_prnum=1234 ;enable inbound bridging - this should be an QSIG-network-wide unique number
|
||||
;divaqsig=on ;enable Diva QSIG and protocol independent implementation
|
||||
;mwifacptynrtype=0;type of MWI facility party number, 0 - unknown (default), 1 - public
|
||||
;mwifacptynrton=0 ;MWI facility party number type of number and numbering plan identification
|
||||
; (coding as for byte 0 of the calling party number).
|
||||
; This byte is only valid if byte mwifacptynrtype contains the value 1
|
||||
;mwifacptynrpres=0;MWI facility party number type presentation and screening indicator
|
||||
; (coding as for byte 1 of the calling party number).
|
||||
; This byte is only valid if byte mwifacptynrtype contains the value 1
|
||||
;mwibasicservice=1;MWI basic Service, coded in accordance with ETS 300 196 [D.5]
|
||||
;mwiinvocation=2 ;MWI invocation mode, 0 - deferred, 1 - immediate, 2 - combined,
|
||||
; 65535 - suppres invocation code
|
||||
;mwimailbox=12345 ;',' separated list of mailboxes for MWI in format:
|
||||
; mailbox[:controlling user number[:controlling user provided number]][@context]
|
||||
;hlimit=10 ;Do not use this controller for outgoing calls if less than 'hlimit' free channels is
|
||||
;left on this controller.
|
||||
;slimit=10 ;Try to use for outgoing calls other controller in group if less than 'slimit' free
|
||||
;channels is left on this controller. Always try to 'fill up' the controller with
|
||||
;smalest number in group. Create call if less than 'slimit' free channels left and
|
||||
;no other controller with respect to free channel count was found in group.
|
||||
|
||||
|
|
2169
chan_capi.c
2169
chan_capi.c
File diff suppressed because it is too large
Load Diff
180
chan_capi.h
180
chan_capi.h
|
@ -49,11 +49,17 @@
|
|||
#ifndef _PBX_CAPI_H
|
||||
#define _PBX_CAPI_H
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
struct _diva_stream_scheduling_entry;
|
||||
#endif
|
||||
struct _pbx_capi_conference_bridge;
|
||||
|
||||
#define CAPI_MAX_CONTROLLERS 64
|
||||
#define CAPI_MAX_B3_BLOCKS 7
|
||||
|
||||
/* was : 130 bytes Alaw = 16.25 ms audio not suitable for VoIP */
|
||||
/* now : 160 bytes Alaw = 20 ms audio */
|
||||
/* now : 640 bytes slinear 16000Hz = 20 ms audio */
|
||||
/* you can tune this to your need. higher value == more latency */
|
||||
#define CAPI_MAX_B3_BLOCK_SIZE 160
|
||||
|
||||
|
@ -66,17 +72,25 @@
|
|||
|
||||
#define CAPI_MAX_FACILITYDATAARRAY_SIZE 300
|
||||
|
||||
#define COMMANDSEPARATOR "|,"
|
||||
|
||||
#ifdef CC_AST_HAS_FORMAT_T
|
||||
typedef format_t cc_format_t;
|
||||
#else
|
||||
typedef int cc_format_t;
|
||||
#endif
|
||||
|
||||
/* some helper functions */
|
||||
static inline void write_capi_word(void *m, unsigned short val)
|
||||
{
|
||||
((unsigned char *)m)[0] = val & 0xff;
|
||||
((unsigned char *)m)[1] = (val >> 8) & 0xff;
|
||||
}
|
||||
static inline unsigned short read_capi_word(void *m)
|
||||
static inline unsigned short read_capi_word(const void *m)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
val = ((unsigned char *)m)[0] | (((unsigned char *)m)[1] << 8);
|
||||
val = ((const unsigned char *)m)[0] | (((const unsigned char *)m)[1] << 8);
|
||||
return (val);
|
||||
}
|
||||
static inline void write_capi_dword(void *m, unsigned int val)
|
||||
|
@ -86,12 +100,12 @@ static inline void write_capi_dword(void *m, unsigned int val)
|
|||
((unsigned char *)m)[2] = (val >> 16) & 0xff;
|
||||
((unsigned char *)m)[3] = (val >> 24) & 0xff;
|
||||
}
|
||||
static inline unsigned int read_capi_dword(void *m)
|
||||
static inline unsigned int read_capi_dword(const void *m)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = ((unsigned char *)m)[0] | (((unsigned char *)m)[1] << 8) |
|
||||
(((unsigned char *)m)[2] << 16) | (((unsigned char *)m)[3] << 24);
|
||||
val = ((const unsigned char *)m)[0] | (((const unsigned char *)m)[1] << 8) |
|
||||
(((const unsigned char *)m)[2] << 16) | (((const unsigned char *)m)[3] << 24);
|
||||
return (val);
|
||||
}
|
||||
|
||||
|
@ -223,6 +237,16 @@ typedef struct fax3proto3 B3_PROTO_FAXG3;
|
|||
#define EC_ECHOCANCEL_PATH_IP 2 /* Activate EC for IP */
|
||||
#define EC_ECHOCANCEL_PATH_BITS (EC_ECHOCANCEL_PATH_IFC | EC_ECHOCANCEL_PATH_IP)
|
||||
|
||||
/*
|
||||
Control EC on transit connectionss
|
||||
*/
|
||||
#define EC_ECHOCANCEL_TRANSIT_OFF 0 /* EC deactivated on transit connection, default */
|
||||
#define EC_ECHOCANCEL_TRANSIT_A 1 /* EC activated on side A of transsit connection */
|
||||
#define EC_ECHOCANCEL_TRANSIT_B 2 /* EC activated on side B of transsit connection */
|
||||
#define EC_ECHOCANCEL_TRANSIT_AB (EC_ECHOCANCEL_TRANSIT_A | EC_ECHOCANCEL_TRANSIT_B)
|
||||
#define EC_ECHOCANCEL_TRANSIT_BITS (EC_ECHOCANCEL_TRANSIT_A | EC_ECHOCANCEL_TRANSIT_B)
|
||||
|
||||
|
||||
#define CC_HOLDTYPE_LOCAL 0
|
||||
#define CC_HOLDTYPE_HOLD 1
|
||||
#define CC_HOLDTYPE_NOTIFY 2
|
||||
|
@ -289,6 +313,9 @@ struct cc_capi_gains {
|
|||
#define CAPI_ISDN_STATE_PBX_DONT 0x40000000
|
||||
#define CAPI_ISDN_STATE_PBX 0x80000000
|
||||
|
||||
#define CAPI_ISDN_STATE2_PROCEEDING 0x00000001
|
||||
#define CAPI_ISDN_STATE2_PROCEEDING_PENDING 0x00000002
|
||||
|
||||
#define CAPI_CHANNELTYPE_B 0
|
||||
#define CAPI_CHANNELTYPE_D 1
|
||||
#define CAPI_CHANNELTYPE_NULL 2
|
||||
|
@ -377,6 +404,7 @@ struct capi_pvt {
|
|||
|
||||
/* the state of the line */
|
||||
unsigned int isdnstate;
|
||||
unsigned int isdnstate2;
|
||||
int cause;
|
||||
|
||||
/* which b-protocol is active */
|
||||
|
@ -455,6 +483,10 @@ struct capi_pvt {
|
|||
unsigned int FaxState;
|
||||
/* Window for fax detection */
|
||||
unsigned int faxdetecttime;
|
||||
/* custom fax context,exten,prio */
|
||||
char faxcontext[AST_MAX_EXTENSION+1];
|
||||
char faxexten[AST_MAX_EXTENSION+1];
|
||||
int faxpriority;
|
||||
|
||||
/* handle for CCBS/CCNR callback */
|
||||
unsigned int ccbsnrhandle;
|
||||
|
@ -474,6 +506,7 @@ struct capi_pvt {
|
|||
float txmin;
|
||||
|
||||
unsigned short divaAudioFlags;
|
||||
unsigned short divaDataStubAudioFlags;
|
||||
unsigned short divaDigitalRxGain;
|
||||
float divaDigitalRxGainDB;
|
||||
unsigned short divaDigitalTxGain;
|
||||
|
@ -513,17 +546,14 @@ struct capi_pvt {
|
|||
#else
|
||||
struct ast_rtp *rtp;
|
||||
#endif
|
||||
#ifdef CC_AST_HAS_FORMAT_T
|
||||
format_t capability;
|
||||
#else
|
||||
int capability;
|
||||
#endif
|
||||
cc_format_t capability;
|
||||
int rtpcodec;
|
||||
int codec;
|
||||
unsigned int timestamp;
|
||||
|
||||
/* Q.SIG features */
|
||||
int qsigfeat;
|
||||
int divaqsig;
|
||||
struct cc_qsig_data qsig_data;
|
||||
|
||||
/* Resource PLCI data */
|
||||
|
@ -533,7 +563,14 @@ struct capi_pvt {
|
|||
struct capi_pvt *line_plci;
|
||||
/* Resource PLCI data data if line */
|
||||
struct capi_pvt *data_plci;
|
||||
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
struct _diva_stream_scheduling_entry* diva_stream_entry;
|
||||
#endif
|
||||
/* Connection between two conference rooms. NULL PLCI */
|
||||
int virtualBridgePeer;
|
||||
struct capi_pvt *bridgePeer;
|
||||
|
||||
/*! Next channel in list */
|
||||
struct capi_pvt *next;
|
||||
};
|
||||
|
@ -580,9 +617,14 @@ struct cc_capi_conf {
|
|||
int bridge;
|
||||
int amaflags;
|
||||
int qsigfeat;
|
||||
int divaqsig;
|
||||
struct cc_capi_qsig_conf qsigconf;
|
||||
unsigned int faxsetting;
|
||||
unsigned int faxdetecttime;
|
||||
/* custom fax context,exten,prio */
|
||||
char faxcontext[AST_MAX_EXTENSION+1];
|
||||
char faxexten[AST_MAX_EXTENSION+1];
|
||||
int faxpriority;
|
||||
ast_group_t callgroup;
|
||||
ast_group_t pickupgroup;
|
||||
ast_group_t group;
|
||||
|
@ -600,8 +642,38 @@ struct cc_capi_conf {
|
|||
char mohinterpret[MAX_MUSICCLASS];
|
||||
#endif
|
||||
int echocancelpath;
|
||||
int econtransitconn;
|
||||
|
||||
int mwifacptynrtype;
|
||||
int mwifacptynrton;
|
||||
int mwifacptynrpres;
|
||||
int mwibasicservice;
|
||||
int mwiinvocation;
|
||||
|
||||
char* mwimailbox;
|
||||
|
||||
int hlimit;
|
||||
int slimit;
|
||||
};
|
||||
|
||||
struct cc_capi_controller;
|
||||
struct _cc_capi_mwi_mailbox;
|
||||
typedef struct _cc_capi_mwi_mailbox {
|
||||
AST_LIST_ENTRY(_cc_capi_mwi_mailbox) link;
|
||||
const struct cc_capi_controller *controller;
|
||||
unsigned short basicService;
|
||||
unsigned short invocationMode;
|
||||
unsigned char *mailboxNumber;
|
||||
char *mailboxContext;
|
||||
unsigned char *controllingUserNumber;
|
||||
unsigned char *controllingUserProvidedNumber;
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
struct ast_event_sub* mwiSubscribtion;
|
||||
#else
|
||||
void* mwiSubscribtion;
|
||||
#endif
|
||||
} cc_capi_mwi_mailbox_t;
|
||||
|
||||
struct cc_capi_controller {
|
||||
/* which controller is this? */
|
||||
int controller;
|
||||
|
@ -611,6 +683,13 @@ struct cc_capi_controller {
|
|||
int nbchannels;
|
||||
/* free bchans */
|
||||
int nfreebchannels;
|
||||
/* Controller considered BUSY amount if free channels below
|
||||
of this level */
|
||||
int nfreebchannelsHardThr;
|
||||
/* If amount of free channels is below this level then
|
||||
try to allocate call on other controler in group
|
||||
where this level is not reached or difference is less */
|
||||
int nfreebchannelsSoftThr;
|
||||
/* features: */
|
||||
int broadband;
|
||||
int dtmf;
|
||||
|
@ -634,21 +713,18 @@ struct cc_capi_controller {
|
|||
|
||||
int divaExtendedFeaturesAvailable;
|
||||
int ecPath;
|
||||
int ecOnTransit;
|
||||
int fax_t30_extended;
|
||||
#ifdef DIVA_STREAMING
|
||||
int divaStreaming;
|
||||
#endif
|
||||
AST_LIST_HEAD_NOLOCK(, _cc_capi_mwi_mailbox) mwiSubscribtions;
|
||||
#ifdef DIVA_STATUS
|
||||
int interfaceState;
|
||||
int hwState;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* ETSI 300 102-1 information element identifiers */
|
||||
#define CAPI_ETSI_IE_CAUSE 0x08
|
||||
#define CAPI_ETSI_IE_PROGRESS_INDICATOR 0x1e
|
||||
#define CAPI_ETSI_IE_CALLED_PARTY_NUMBER 0x70
|
||||
#define CAPI_ETSI_IE_FACILITY 0x1c
|
||||
|
||||
/* ETIS 300 102-1 message types */
|
||||
#define CAPI_ETSI_ALERTING 0x01
|
||||
#define CAPI_ETSI_SETUP_ACKKNOWLEDGE 0x0d
|
||||
#define CAPI_ETSI_DISCONNECT 0x45
|
||||
|
||||
/* ETSI 300 102-1 Numbering Plans */
|
||||
#define CAPI_ETSI_NPLAN_SUBSCRIBER 0x40
|
||||
#define CAPI_ETSI_NPLAN_NATIONAL 0x20
|
||||
|
@ -701,7 +777,7 @@ extern void cc_start_b3(struct capi_pvt *i);
|
|||
extern unsigned char capi_tcap_is_digital(unsigned short tcap);
|
||||
extern void capi_queue_cause_control(struct capi_pvt *i, int control);
|
||||
extern void capidev_handle_connection_conf(struct capi_pvt **i, unsigned int PLCI,
|
||||
unsigned short wInfo, unsigned short wMsgNum);
|
||||
unsigned short wInfo, unsigned short wMsgNum, struct ast_channel** interface_owner);
|
||||
extern void capi_wait_for_answered(struct capi_pvt *i);
|
||||
extern int capi_wait_for_b3_up(struct capi_pvt *i);
|
||||
extern void capi_activehangup(struct capi_pvt *i, int state);
|
||||
|
@ -712,6 +788,51 @@ extern char chatinfo_usage[];
|
|||
|
||||
typedef int (*pbx_capi_command_proc_t)(struct ast_channel *, char *);
|
||||
pbx_capi_command_proc_t pbx_capi_lockup_command_by_name(const char* name);
|
||||
/*!
|
||||
* \brief returns list of supported by this controller RTP codecs
|
||||
*/
|
||||
cc_format_t pbx_capi_get_controller_codecs(int controller);
|
||||
_cstruct diva_get_b1_conf(struct capi_pvt *i);
|
||||
/*!
|
||||
\brief &capi_controllers[controller]
|
||||
*/
|
||||
const struct cc_capi_controller *pbx_capi_get_controller(int controller);
|
||||
/*!
|
||||
\brief capi_num_controllers
|
||||
*/
|
||||
int pbx_capi_get_num_controllers(void);
|
||||
/*!
|
||||
\brief tdesc
|
||||
*/
|
||||
const char* pbx_capi_get_module_description(void);
|
||||
/*!
|
||||
\brief cc_mutex_lock(&iflock)
|
||||
*/
|
||||
void pbx_capi_lock_interfaces(void);
|
||||
/*!
|
||||
\brief cc_mutex_unlock(&iflock)
|
||||
*/
|
||||
void pbx_capi_unlock_interfaces(void);
|
||||
/*!
|
||||
\brief Exec cappicommand using CLI
|
||||
*/
|
||||
int pbx_capi_cli_exec_capicommand(struct ast_channel *chan, const char *data);
|
||||
|
||||
/*!
|
||||
\brief EC control
|
||||
*/
|
||||
void capi_echo_canceller(struct capi_pvt *i, int function);
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
struct _diva_streaming_vector;
|
||||
void capidev_handle_data_b3_indication_vector (struct capi_pvt *i,
|
||||
struct _diva_streaming_vector* vind,
|
||||
int vind_nr);
|
||||
/*!
|
||||
* \brief Return true if Diva streaming supported by CAPI controller
|
||||
*/
|
||||
int pbx_capi_streaming_supported (struct capi_pvt *i);
|
||||
#endif
|
||||
|
||||
/* DIVA specific MANUFACTURER definitions */
|
||||
#define _DI_MANU_ID 0x44444944
|
||||
|
@ -719,5 +840,16 @@ pbx_capi_command_proc_t pbx_capi_lockup_command_by_name(const char* name);
|
|||
#define _DI_DSP_CTRL 0x0003
|
||||
#define _DI_OPTIONS_REQUEST 0x0009
|
||||
|
||||
#if (!defined(CC_AST_HAS_VERSION_1_4) && !defined(CC_AST_HAS_VERSION_1_6) && !defined(CC_AST_HAS_VERSION_1_8))
|
||||
|
||||
#define ast_malloc(__x__) malloc((__x__))
|
||||
#define ast_free(__x__) free((__x__))
|
||||
#define ast_strdup(__x__) strdup((__x__))
|
||||
#define ast_channel_trylock(__x__) ast_mutex_trylock(&(__x__)->lock)
|
||||
#define ast_channel_unlock(__x__) ast_mutex_unlock(&(__x__)->lock)
|
||||
#define ast_devstate_prov_add(__a__,__b__) (-1)
|
||||
#define ast_devstate_prov_del(__x__) do{}while(0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Based on apps/app_meetme.c
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
#include "chan_capi_management_common.h"
|
||||
#include "asterisk/manager.h"
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
|
||||
#define CC_AMI_ACTION_NAME_CHATLIST "CapichatList"
|
||||
#define CC_AMI_ACTION_NAME_CHATMUTE "CapichatMute"
|
||||
#define CC_AMI_ACTION_NAME_CHATUNMUTE "CapichatUnmute"
|
||||
#define CC_AMI_ACTION_NAME_CHATREMOVE "CapichatRemove"
|
||||
#define CC_AMI_ACTION_NAME_CAPICOMMAND "CapiCommand"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_mute(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_unmute(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_remove(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_control(struct mansession *s, const struct message *m, int chatMute);
|
||||
static int pbx_capi_ami_capicommand(struct mansession *s, const struct message *m);
|
||||
static int capiChatListRegistered;
|
||||
static int capiChatMuteRegistered;
|
||||
static int capiChatUnmuteRegistered;
|
||||
static int capiChatRemoveRegistered;
|
||||
static int capiCommandRegistered;
|
||||
|
||||
static char mandescr_capichatlist[] =
|
||||
"Description: Lists all users in a particular CapiChat conference.\n"
|
||||
"CapichatList will follow as separate events, followed by a final event called\n"
|
||||
"CapichatListComplete.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n";
|
||||
|
||||
static char mandescr_capichatmute[] =
|
||||
"Description: Mutes user in a particular CapiChat conference.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n"
|
||||
" *Member: <membername>\n"
|
||||
" *Path: <Rx or Tx>\n";
|
||||
|
||||
static char mandescr_capichatunmute[] =
|
||||
"Description: Unmutes user in a particular CapiChat conference.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n"
|
||||
" *Member: <membername>\n"
|
||||
" *Path: <Rx or Tx>\n";
|
||||
|
||||
static char mandescr_capichatremove[] =
|
||||
"Description: Removes user in a particular CapiChat conference.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n"
|
||||
" *Member: <membername>\n";
|
||||
|
||||
static char mandescr_capicommand[] =
|
||||
"Description: Exec capicommand.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Channel: <channame>\n"
|
||||
" *Capicommand: <capicommand>\n";
|
||||
|
||||
void pbx_capi_ami_register(void)
|
||||
{
|
||||
capiChatListRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATLIST,
|
||||
EVENT_FLAG_REPORTING,
|
||||
pbx_capi_ami_capichat_list,
|
||||
"List participants in a conference",
|
||||
mandescr_capichatlist) == 0;
|
||||
|
||||
capiChatMuteRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATMUTE,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capichat_mute,
|
||||
"Mute a conference user",
|
||||
mandescr_capichatmute) == 0;
|
||||
|
||||
capiChatUnmuteRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATUNMUTE,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capichat_unmute,
|
||||
"Unmute a conference user",
|
||||
mandescr_capichatunmute) == 0;
|
||||
|
||||
capiChatRemoveRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATREMOVE,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capichat_remove,
|
||||
"Remove a conference user",
|
||||
mandescr_capichatremove) == 0;
|
||||
|
||||
capiCommandRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CAPICOMMAND,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capicommand,
|
||||
"Exec capicommand",
|
||||
mandescr_capicommand) == 0;
|
||||
}
|
||||
|
||||
void pbx_capi_ami_unregister(void)
|
||||
{
|
||||
if (capiChatListRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATLIST);
|
||||
|
||||
if (capiChatMuteRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATMUTE);
|
||||
|
||||
if (capiChatUnmuteRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATUNMUTE);
|
||||
|
||||
if (capiChatRemoveRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATREMOVE);
|
||||
|
||||
if (capiCommandRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CAPICOMMAND);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message *m) {
|
||||
const char *actionid = astman_get_header(m, "ActionID");
|
||||
const char *conference = astman_get_header(m, "Conference");
|
||||
char idText[80] = "";
|
||||
int total = 0;
|
||||
const struct capichat_s *capiChatRoom;
|
||||
|
||||
if (!ast_strlen_zero(actionid))
|
||||
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
|
||||
|
||||
if (pbx_capi_chat_get_room_c(NULL) == NULL) {
|
||||
astman_send_error(s, m, "No active conferences.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
astman_send_listack(s, m, CC_AMI_ACTION_NAME_CHATLIST" user list will follow", "start");
|
||||
|
||||
/* Find the right conference */
|
||||
pbx_capi_lock_chat_rooms();
|
||||
|
||||
for (capiChatRoom = pbx_capi_chat_get_room_c(NULL), total = 0;
|
||||
capiChatRoom != NULL;
|
||||
capiChatRoom = pbx_capi_chat_get_room_c(capiChatRoom)) {
|
||||
const char* roomName = pbx_capi_chat_get_room_name(capiChatRoom);
|
||||
/* If we ask for one particular, and this isn't it, skip it */
|
||||
if (!ast_strlen_zero(conference) && strcmp(roomName, conference))
|
||||
continue;
|
||||
|
||||
{
|
||||
unsigned int roomNumber = pbx_capi_chat_get_room_number(capiChatRoom);
|
||||
struct ast_channel *c = pbx_capi_chat_get_room_channel(capiChatRoom);
|
||||
const struct capi_pvt* i = pbx_capi_chat_get_room_interface_c(capiChatRoom);
|
||||
int isMemberOperator = pbx_capi_chat_is_member_operator(capiChatRoom);
|
||||
int isCapiChatRoomMuted = pbx_capi_chat_is_room_muted(capiChatRoom);
|
||||
int isCapiChatMemberMuted = pbx_capi_chat_is_member_muted(capiChatRoom);
|
||||
int isCapiChatMemberListener = pbx_capi_chat_is_member_listener(capiChatRoom);
|
||||
int isCapiChatMostRecentMember = pbx_capi_chat_is_most_recent_user(capiChatRoom);
|
||||
const char* mutedVisualName = "No";
|
||||
char* cidVisual;
|
||||
char* callerNameVisual;
|
||||
|
||||
if ((c == NULL) || (i == NULL))
|
||||
continue;
|
||||
|
||||
cidVisual = ast_strdup(pbx_capi_get_cid (c, "<unknown>"));
|
||||
callerNameVisual = ast_strdup(pbx_capi_get_callername (c, "<no name>"));
|
||||
|
||||
if (isCapiChatMemberListener || isCapiChatRoomMuted || isCapiChatMemberMuted) {
|
||||
if (isMemberOperator) {
|
||||
if (isCapiChatMemberMuted)
|
||||
mutedVisualName = "By self";
|
||||
} else if (isCapiChatMemberListener || isCapiChatRoomMuted) {
|
||||
mutedVisualName = "By admin";
|
||||
} else {
|
||||
mutedVisualName = "By self";
|
||||
}
|
||||
}
|
||||
|
||||
total++;
|
||||
astman_append(s,
|
||||
"Event: "CC_AMI_ACTION_NAME_CHATLIST"\r\n"
|
||||
"%s"
|
||||
"Conference: %s/%u\r\n"
|
||||
"UserNumber: %d\r\n"
|
||||
"CallerIDNum: %s\r\n"
|
||||
"CallerIDName: %s\r\n"
|
||||
"Channel: %s\r\n"
|
||||
"Admin: %s\r\n"
|
||||
"Role: %s\r\n"
|
||||
"MarkedUser: %s\r\n"
|
||||
"Muted: %s\r\n"
|
||||
"Talking: %s\r\n"
|
||||
"Domain: %s\r\n"
|
||||
"DTMF: %s\r\n"
|
||||
"EchoCancel: %s\r\n"
|
||||
"NoiseSupp: %s\r\n"
|
||||
"RxAGC: %s\r\n"
|
||||
"TxAGC: %s\r\n"
|
||||
"RxGain: %.1f%s\r\n"
|
||||
"TxGain: %.1f%s\r\n"
|
||||
"\r\n",
|
||||
idText,
|
||||
roomName,
|
||||
roomNumber,
|
||||
total,
|
||||
(cidVisual != 0) ? cidVisual : "?",
|
||||
(callerNameVisual != 0) ? callerNameVisual : "?",
|
||||
c->name,
|
||||
(isMemberOperator != 0) ? "Yes" : "No",
|
||||
(isCapiChatMemberListener != 0) ? "Listen only" : "Talk and listen" /* "Talk only" */,
|
||||
(isCapiChatMostRecentMember != 0) ? "Yes" : "No",
|
||||
mutedVisualName,
|
||||
/* "Yes" "No" */ "Not monitored",
|
||||
(i->channeltype == CAPI_CHANNELTYPE_B) ? "TDM" : "IP",
|
||||
(i->isdnstate & CAPI_ISDN_STATE_DTMF) ? "Y" : "N",
|
||||
(i->isdnstate & CAPI_ISDN_STATE_EC) ? "Y" : "N",
|
||||
(i->divaAudioFlags & 0x0080) ? "Y" : "N", /* Noise supression */
|
||||
(i->divaAudioFlags & 0x0008) ? "Y" : "N", /* Rx AGC */
|
||||
(i->divaAudioFlags & 0x0004) ? "Y" : "N", /* Tx AGC */
|
||||
i->divaDigitalRxGainDB, "dB",
|
||||
i->divaDigitalTxGainDB, "dB");
|
||||
|
||||
ast_free (cidVisual);
|
||||
ast_free (callerNameVisual);
|
||||
}
|
||||
}
|
||||
pbx_capi_unlock_chat_rooms();
|
||||
/* Send final confirmation */
|
||||
astman_append(s,
|
||||
"Event: "CC_AMI_ACTION_NAME_CHATLIST"Complete\r\n"
|
||||
"EventList: Complete\r\n"
|
||||
"ListItems: %d\r\n"
|
||||
"%s"
|
||||
"\r\n", total, idText);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_mute(struct mansession *s, const struct message *m)
|
||||
{
|
||||
return pbx_capi_ami_capichat_control(s, m, 1);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_unmute(struct mansession *s, const struct message *m)
|
||||
{
|
||||
return pbx_capi_ami_capichat_control(s, m, 0);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_control(struct mansession *s, const struct message *m, int chatMute)
|
||||
{
|
||||
const char *roomName = astman_get_header(m, "Conference");
|
||||
const char *userName = astman_get_header(m, "Member");
|
||||
const char *voicePath = astman_get_header(m, "Path");
|
||||
const char* capiCommand;
|
||||
int ret;
|
||||
|
||||
if (ast_strlen_zero(roomName)) {
|
||||
astman_send_error(s, m, "Capi Chat conference not specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(userName)) {
|
||||
char* param = ast_strdupa((chatMute != 0) ? "yes" : "no");
|
||||
int ret = pbx_capi_chat_mute(NULL, param);
|
||||
if (ret == 0) {
|
||||
astman_send_ack(s, m, (chatMute != 0) ? "Conference muted" : "Conference unmuted");
|
||||
} else {
|
||||
astman_send_error(s, m, "Failed to change mode of Capi Chat conference");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((voicePath != NULL) && (strcmp(voicePath, "Rx") == 0)) {
|
||||
capiCommand = (chatMute != 0) ? "rxdgain,-128" : "rxdgain,0";
|
||||
} else {
|
||||
capiCommand = (chatMute != 0) ? "txdgain,-128" : "txdgain,0";
|
||||
}
|
||||
|
||||
ret = pbx_capi_management_capicommand(userName, capiCommand);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
astman_send_ack(s, m, (chatMute != 0) ? "User muted" : "User unmuted");
|
||||
break;
|
||||
|
||||
case -4:
|
||||
astman_send_error(s, m, "User not found");
|
||||
break;
|
||||
|
||||
default:
|
||||
astman_send_error(s, m, "Command error");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_remove(struct mansession *s, const struct message *m)
|
||||
{
|
||||
const char *roomName = astman_get_header(m, "Conference");
|
||||
const char *userName = astman_get_header(m, "Member");
|
||||
int ret;
|
||||
|
||||
if (ast_strlen_zero(roomName)) {
|
||||
astman_send_error(s, m, "Capi Chat conference not specified");
|
||||
return 0;
|
||||
}
|
||||
if (ast_strlen_zero(userName)) {
|
||||
astman_send_error(s, m, "Capi Chat member not specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = pbx_capi_chat_remove_user (roomName, userName);
|
||||
if (ret == 0) {
|
||||
astman_send_ack(s, m, "Member removed");
|
||||
} else {
|
||||
astman_send_error(s, m, "Member not found");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capicommand(struct mansession *s, const struct message *m)
|
||||
{
|
||||
const char *requiredChannelName = astman_get_header(m, "Channel");
|
||||
const char *chancapiCommand = astman_get_header(m, "Command");
|
||||
int ret = pbx_capi_management_capicommand(requiredChannelName, chancapiCommand);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
astman_send_ack(s, m, "OK");
|
||||
break;
|
||||
|
||||
case -2:
|
||||
astman_send_error(s, m, "Channel name not specified");
|
||||
break;
|
||||
|
||||
case -3:
|
||||
astman_send_error(s, m, "Capi command name not specified");
|
||||
break;
|
||||
|
||||
case -4:
|
||||
astman_send_error(s, m, "Channel not found");
|
||||
break;
|
||||
|
||||
case -1:
|
||||
default:
|
||||
astman_send_error(s, m, "Command error");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
void pbx_capi_ami_register(void)
|
||||
{
|
||||
}
|
||||
void pbx_capi_ami_unregister(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void pbx_capi_chat_join_event(struct ast_channel* c, const struct capichat_s * room)
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
ast_manager_event(c,
|
||||
#else
|
||||
manager_event(
|
||||
#endif
|
||||
EVENT_FLAG_CALL, "CapichatJoin",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Conference: %s\r\n"
|
||||
"Conferencenum: %u\r\n"
|
||||
"CallerIDnum: %s\r\n"
|
||||
"CallerIDname: %s\r\n",
|
||||
c->name, c->uniqueid,
|
||||
pbx_capi_chat_get_room_name(room),
|
||||
pbx_capi_chat_get_room_number(room),
|
||||
pbx_capi_get_cid (c, "<unknown>"),
|
||||
pbx_capi_get_callername (c, "<no name>"));
|
||||
}
|
||||
|
||||
void pbx_capi_chat_leave_event(struct ast_channel* c,
|
||||
const struct capichat_s *room,
|
||||
long duration)
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
ast_manager_event(c,
|
||||
#else
|
||||
manager_event(
|
||||
#endif
|
||||
EVENT_FLAG_CALL, "CapichatLeave",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Conference: %s\r\n"
|
||||
"Conferencenum: %u\r\n"
|
||||
"CallerIDNum: %s\r\n"
|
||||
"CallerIDName: %s\r\n"
|
||||
"Duration: %ld\r\n",
|
||||
c->name, c->uniqueid,
|
||||
pbx_capi_chat_get_room_name(room),
|
||||
pbx_capi_chat_get_room_number(room),
|
||||
pbx_capi_get_cid (c, "<unknown>"),
|
||||
pbx_capi_get_callername (c, "<no name>"),
|
||||
duration);
|
||||
}
|
||||
|
||||
void pbx_capi_chat_conference_end_event(const char* roomName)
|
||||
{
|
||||
manager_event(EVENT_FLAG_CALL, "CapichatEnd", "Conference: %s\r\n", roomName);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Based on apps/app_meetme.c
|
||||
*
|
||||
*/
|
||||
#ifndef __CC_AMI_INTERFACE_H__
|
||||
#define __CC_AMI_INTERFACE_H__
|
||||
|
||||
void pbx_capi_ami_register(void);
|
||||
void pbx_capi_ami_unregister(void);
|
||||
struct capichat_s;
|
||||
void pbx_capi_chat_join_event(struct ast_channel* c, const struct capichat_s * room);
|
||||
void pbx_capi_chat_leave_event(struct ast_channel* c,
|
||||
const struct capichat_s *room,
|
||||
long duration);
|
||||
void pbx_capi_chat_conference_end_event(const char* roomName);
|
||||
|
||||
|
||||
#endif
|
||||
|
923
chan_capi_chat.c
923
chan_capi_chat.c
File diff suppressed because it is too large
Load Diff
|
@ -15,6 +15,7 @@
|
|||
/*
|
||||
* prototypes
|
||||
*/
|
||||
extern void pbx_capi_chat_init_module(void);
|
||||
extern int pbx_capi_chat(struct ast_channel *c, char *param);
|
||||
extern int pbx_capi_chat_associate_resource_plci(struct ast_channel *c, char *param);
|
||||
extern struct capi_pvt* pbx_check_resource_plci(struct ast_channel *c);
|
||||
|
@ -26,5 +27,25 @@ extern int pbxcli_capi_chatinfo(int fd, int argc, char *argv[]);
|
|||
extern int pbx_capi_chat_command (struct ast_channel *c, char *param);
|
||||
extern int pbx_capi_chat_mute(struct ast_channel *c, char *param);
|
||||
extern int pbx_capi_chat_play(struct ast_channel *c, char *param);
|
||||
extern int pbx_capi_chat_connect(struct ast_channel *c, char *param);
|
||||
int pbx_capi_chat_remove_user(const char* room, const char* name);
|
||||
|
||||
struct capichat_s;
|
||||
const struct capichat_s *pbx_capi_chat_get_room_c(const struct capichat_s * room);
|
||||
const char* pbx_capi_chat_get_room_name(const struct capichat_s * room);
|
||||
unsigned int pbx_capi_chat_get_room_number(const struct capichat_s * room);
|
||||
unsigned int pbx_capi_chat_get_room_members(const struct capichat_s * room);
|
||||
struct ast_channel *pbx_capi_chat_get_room_channel(const struct capichat_s * room);
|
||||
const struct capi_pvt* pbx_capi_chat_get_room_interface_c(const struct capichat_s * room);
|
||||
int pbx_capi_chat_is_member_operator(const struct capichat_s * room);
|
||||
int pbx_capi_chat_is_room_muted(const struct capichat_s * room);
|
||||
int pbx_capi_chat_is_member_muted(const struct capichat_s * room);
|
||||
int pbx_capi_chat_is_member_listener(const struct capichat_s * room);
|
||||
int pbx_capi_chat_is_most_recent_user(const struct capichat_s * room);
|
||||
unsigned int pbx_capi_chat_get_room_group (const struct capichat_s * room);
|
||||
unsigned int pbx_capi_chat_get_room_group_members (const struct capichat_s * room);
|
||||
|
||||
void pbx_capi_lock_chat_rooms(void);
|
||||
void pbx_capi_unlock_chat_rooms(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
* An implementation of Common ISDN API 2.0 for Asterisk
|
||||
*
|
||||
* Copyright (C) 2005-2010 Cytronics & Melware
|
||||
*
|
||||
* Armin Schindler <armin@melware.de>
|
||||
*
|
||||
* Reworked, but based on the work of
|
||||
* Copyright (C) 2002-2005 Junghanns.NET GmbH
|
||||
*
|
||||
* Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
|
||||
*
|
||||
* This program is free software and may be modified and
|
||||
* distributed under the terms of the GNU Public License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
#include "chan_capi_cli.h"
|
||||
#include "chan_capi_management_common.h"
|
||||
#ifdef DIVA_STREAMING
|
||||
#include "platform.h"
|
||||
#include "chan_capi_divastreaming_utils.h"
|
||||
#endif
|
||||
#ifdef DIVA_STATUS
|
||||
#include "divastatus_ifc.h"
|
||||
#endif
|
||||
#ifdef DIVA_VERBOSE
|
||||
#include "divaverbose.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* usages
|
||||
*/
|
||||
static char info_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " info\n"
|
||||
" Show info about B channels on controllers.\n";
|
||||
|
||||
static char show_channels_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " show channels\n"
|
||||
" Show info about B channels.\n";
|
||||
|
||||
static char show_resources_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " show ressources\n"
|
||||
" Show info about used by channels resources.\n";
|
||||
|
||||
static char show_bridges_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " show bridges\n"
|
||||
" Show info about used conference bridges.\n";
|
||||
|
||||
static char debug_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " debug\n"
|
||||
" Enables dumping of " CC_MESSAGE_BIGNAME " packets for debugging purposes\n";
|
||||
|
||||
static char no_debug_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " no debug\n"
|
||||
" Disables dumping of " CC_MESSAGE_BIGNAME " packets for debugging purposes\n";
|
||||
|
||||
static char qsig_debug_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " qsig debug\n"
|
||||
" Enables dumping of QSIG facilities for debugging purposes\n";
|
||||
|
||||
static char qsig_no_debug_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " qsig no debug\n"
|
||||
" Disables dumping of QSIG facilities for debugging purposes\n";
|
||||
|
||||
static char show_exec_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " info\n"
|
||||
" Exec chancapi command on selected interface (exec interface command parameters).\n";
|
||||
|
||||
static char show_chat_manage_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " chat manage\n"
|
||||
" Manage chat conference (chat manage room member command parameters).\n";
|
||||
|
||||
#ifndef CC_AST_HAS_VERSION_1_6
|
||||
static
|
||||
#endif
|
||||
char chatinfo_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " chatinfo\n"
|
||||
" Show info about chat status.\n";
|
||||
|
||||
#define CC_CLI_TEXT_INFO "Show " CC_MESSAGE_BIGNAME " info"
|
||||
#define CC_CLI_TEXT_SHOW_CHANNELS "Show B-channel info"
|
||||
#define CC_CLI_TEXT_DEBUG "Enable " CC_MESSAGE_BIGNAME " debugging"
|
||||
#define CC_CLI_TEXT_NO_DEBUG "Disable " CC_MESSAGE_BIGNAME " debugging"
|
||||
#define CC_CLI_TEXT_QSIG_DEBUG "Enable QSIG debugging"
|
||||
#define CC_CLI_TEXT_QSIG_NO_DEBUG "Disable QSIG debugging"
|
||||
#define CC_CLI_TEXT_CHATINFO "Show " CC_MESSAGE_BIGNAME " chat info"
|
||||
#define CC_CLI_TEXT_SHOW_RESOURCES "Show used resources"
|
||||
#define CC_CLI_TEXT_SHOW_BRIDGES "Show used conference bridges"
|
||||
#define CC_CLI_TEXT_EXEC_CAPICOMMAND "Exec command"
|
||||
#define CC_CLI_TEXT_CHAT_MANAGE "Manager chat conference"
|
||||
|
||||
/*
|
||||
* helper functions to convert conf value to string
|
||||
*/
|
||||
static char *show_bproto(int bproto)
|
||||
{
|
||||
switch(bproto) {
|
||||
case CC_BPROTO_TRANSPARENT:
|
||||
return "trans";
|
||||
case CC_BPROTO_FAXG3:
|
||||
case CC_BPROTO_FAX3_BASIC:
|
||||
return " fax ";
|
||||
case CC_BPROTO_RTP:
|
||||
return " rtp ";
|
||||
case CC_BPROTO_VOCODER:
|
||||
return " vocoder ";
|
||||
}
|
||||
return " ??? ";
|
||||
}
|
||||
|
||||
static char *show_state(int state)
|
||||
{
|
||||
switch(state) {
|
||||
case CAPI_STATE_ALERTING:
|
||||
return "Ring ";
|
||||
case CAPI_STATE_CONNECTED:
|
||||
return "Conn ";
|
||||
case CAPI_STATE_DISCONNECTING:
|
||||
return "discP";
|
||||
case CAPI_STATE_DISCONNECTED:
|
||||
return "Disc ";
|
||||
case CAPI_STATE_CONNECTPENDING:
|
||||
return "Dial ";
|
||||
case CAPI_STATE_ANSWERING:
|
||||
return "Answ ";
|
||||
case CAPI_STATE_DID:
|
||||
return "DIDin";
|
||||
case CAPI_STATE_INCALL:
|
||||
return "icall";
|
||||
case CAPI_STATE_ONHOLD:
|
||||
return "Hold ";
|
||||
}
|
||||
return "-----";
|
||||
}
|
||||
|
||||
static char *show_isdnstate(unsigned int isdnstate, char *str)
|
||||
{
|
||||
str[0] = '\0';
|
||||
|
||||
if (isdnstate & CAPI_ISDN_STATE_PBX)
|
||||
strcat(str, "*");
|
||||
if (isdnstate & CAPI_ISDN_STATE_LI)
|
||||
strcat(str, "G");
|
||||
if (isdnstate & CAPI_ISDN_STATE_B3_UP)
|
||||
strcat(str, "B");
|
||||
if (isdnstate & CAPI_ISDN_STATE_B3_PEND)
|
||||
strcat(str, "b");
|
||||
if (isdnstate & CAPI_ISDN_STATE_PROGRESS)
|
||||
strcat(str, "P");
|
||||
if (isdnstate & CAPI_ISDN_STATE_HOLD)
|
||||
strcat(str, "H");
|
||||
if (isdnstate & CAPI_ISDN_STATE_ECT)
|
||||
strcat(str, "T");
|
||||
if (isdnstate & CAPI_ISDN_STATE_3PTY)
|
||||
strcat(str, "3");
|
||||
if (isdnstate & (CAPI_ISDN_STATE_SETUP | CAPI_ISDN_STATE_SETUP_ACK))
|
||||
strcat(str, "S");
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* do command capi show channels
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
struct capi_pvt *i;
|
||||
char iochar;
|
||||
char i_state[80];
|
||||
char b3q[32];
|
||||
int required_args;
|
||||
int provided_args;
|
||||
const char* required_channel_name = NULL;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " show channels";
|
||||
e->usage = show_channels_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
required_args = e->args;
|
||||
provided_args = a->argc;
|
||||
if (required_args < provided_args) {
|
||||
required_channel_name = a->argv[required_args];
|
||||
}
|
||||
#else
|
||||
required_args = 3;
|
||||
provided_args = argc;
|
||||
if (required_args < provided_args) {
|
||||
required_channel_name = argv[required_args];
|
||||
}
|
||||
#endif
|
||||
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " B-channel information:\n");
|
||||
ast_cli(fd, "Line-Name NTmode state i/o bproto isdnstate ton number\n");
|
||||
ast_cli(fd, "----------------------------------------------------------------\n");
|
||||
|
||||
pbx_capi_lock_interfaces();
|
||||
|
||||
for (i = capi_iflist; i; i = i->next) {
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_B)
|
||||
continue;
|
||||
if ((required_channel_name != NULL) && (strcmp(required_channel_name, i->vname) != 0))
|
||||
continue;
|
||||
|
||||
if ((i->state == 0) || (i->state == CAPI_STATE_DISCONNECTED))
|
||||
iochar = '-';
|
||||
else if (i->outgoing)
|
||||
iochar = 'O';
|
||||
else
|
||||
iochar = 'I';
|
||||
|
||||
if (capidebug) {
|
||||
snprintf(b3q, sizeof(b3q), " B3q=%d B3count=%d",
|
||||
i->B3q, i->B3count);
|
||||
} else {
|
||||
b3q[0] = '\0';
|
||||
}
|
||||
|
||||
ast_cli(fd,
|
||||
"%-16s %s %s %c %s %-10s 0x%02x '%s'->'%s'%s\n",
|
||||
i->vname,
|
||||
i->ntmode ? "yes":"no ",
|
||||
show_state(i->state),
|
||||
iochar,
|
||||
show_bproto(i->bproto),
|
||||
show_isdnstate(i->isdnstate, i_state),
|
||||
i->cid_ton,
|
||||
i->cid,
|
||||
i->dnid,
|
||||
b3q
|
||||
);
|
||||
}
|
||||
|
||||
pbx_capi_unlock_interfaces();
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* do command capi show resources
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_show_resources(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_show_resources(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int ifc_type;
|
||||
const struct capi_pvt *i;
|
||||
int required_args;
|
||||
int provided_args;
|
||||
const char* required_channel_name = NULL;
|
||||
struct {
|
||||
const struct capi_pvt *head;
|
||||
void (*lock_proc)(void);
|
||||
void (*unlock_proc)(void);
|
||||
} data[2];
|
||||
|
||||
data[0].head = capi_iflist;
|
||||
data[0].lock_proc = pbx_capi_lock_interfaces;
|
||||
data[0].unlock_proc = pbx_capi_unlock_interfaces;
|
||||
data[1].head = pbx_capi_get_nulliflist();
|
||||
data[1].lock_proc = pbx_capi_nulliflist_lock;
|
||||
data[1].unlock_proc = pbx_capi_nulliflist_unlock;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " show resources";
|
||||
e->usage = show_resources_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
required_args = e->args;
|
||||
provided_args = a->argc;
|
||||
if (required_args < provided_args) {
|
||||
required_channel_name = a->argv[required_args];
|
||||
}
|
||||
#else
|
||||
required_args = 3;
|
||||
provided_args = argc;
|
||||
if (required_args < provided_args) {
|
||||
required_channel_name = argv[required_args];
|
||||
}
|
||||
#endif
|
||||
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " resources in use:\n");
|
||||
ast_cli(fd, "%-40s %-6s %-4s %-10s %-9s %-5s %-5s %-6s %-6s %-6s %-7s\n",
|
||||
"Line-Name", "Domain", "DTMF", "EchoCancel", "NoiseSupp", "RxAGC", "TxAGC", "RxGain", "TxGain", "CAPI", "Queue");
|
||||
ast_cli(fd, "-----------------------------------------------------------------------------------------------------------------\n");
|
||||
|
||||
for (ifc_type = 0; ifc_type < sizeof(data)/sizeof(data[0]); ifc_type++) {
|
||||
data[ifc_type].lock_proc();
|
||||
|
||||
for (i = data[ifc_type].head; i; i = i->next) {
|
||||
unsigned int queueDepth = 0;
|
||||
char* name;
|
||||
|
||||
if (((i->used == 0) && (i->channeltype != CAPI_CHANNELTYPE_NULL)) || ((i->channeltype != CAPI_CHANNELTYPE_B) &&
|
||||
(i->channeltype != CAPI_CHANNELTYPE_NULL)))
|
||||
continue;
|
||||
if (i->data_plci != 0)
|
||||
continue;
|
||||
|
||||
name = ast_strdup(i->vname);
|
||||
if ((i->channeltype == CAPI_CHANNELTYPE_NULL) && (name != NULL)) {
|
||||
char* p = strstr(name, "-DATAPLCI");
|
||||
if (p != NULL)
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if ((required_channel_name != NULL) &&
|
||||
(strcmp(required_channel_name, (name == 0) ? i->vname : name) != 0)) {
|
||||
ast_free(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
queueDepth = capi_DivaStreamingGetStreamInUse(i->line_plci == NULL ? i : i->line_plci);
|
||||
#endif
|
||||
|
||||
ast_cli(fd, "%-40s %-6s %-4s %-10s %-9s %-5s %-5s %-.1f%-3s %-.1f%-3s%5d %7u\n",
|
||||
(name == 0) ? i->vname : name,
|
||||
(i->channeltype == CAPI_CHANNELTYPE_B) ? "TDM" : "IP",
|
||||
(i->isdnstate & CAPI_ISDN_STATE_DTMF) ? "Y" : "N",
|
||||
(i->isdnstate & CAPI_ISDN_STATE_EC) ? "Y" : "N",
|
||||
(i->divaAudioFlags & 0x0080) ? "Y" : "N", /* Noise supression */
|
||||
(i->divaAudioFlags & 0x0008) ? "Y" : "N", /* Rx AGC */
|
||||
(i->divaAudioFlags & 0x0004) ? "Y" : "N", /* Tx AGC */
|
||||
i->divaDigitalRxGainDB, "dB",
|
||||
i->divaDigitalTxGainDB, "dB",
|
||||
i->controller,
|
||||
queueDepth);
|
||||
ast_free (name);
|
||||
}
|
||||
|
||||
data[ifc_type].unlock_proc();
|
||||
}
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* do command capi show bridges
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_show_bridges(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_show_bridges(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
const struct capichat_s *capiChatRoom;
|
||||
int required_args;
|
||||
int provided_args;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " show bridges";
|
||||
e->usage = show_bridges_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
required_args = e->args;
|
||||
provided_args = a->argc;
|
||||
#else
|
||||
required_args = 3;
|
||||
provided_args = argc;
|
||||
#endif
|
||||
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " conference bridges in use:\n");
|
||||
ast_cli(fd, "%-17s %-5s %-7s %-4s %-11s\n",
|
||||
"Bridge", "Group", "Members", "CAPI", "Queue depth");
|
||||
ast_cli(fd, "----------------------------------------------------------------------------------------------------------\n");
|
||||
|
||||
pbx_capi_lock_chat_rooms();
|
||||
for (capiChatRoom = pbx_capi_chat_get_room_c(NULL);
|
||||
capiChatRoom != NULL;
|
||||
capiChatRoom = pbx_capi_chat_get_room_c(capiChatRoom)) {
|
||||
const struct capi_pvt* i = pbx_capi_chat_get_room_interface_c(capiChatRoom);
|
||||
|
||||
if ((i->virtualBridgePeer == 0) || (i->bridgePeer == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int groupNumber = pbx_capi_chat_get_room_group (capiChatRoom);
|
||||
if (groupNumber > 0) {
|
||||
const char* roomName = pbx_capi_chat_get_room_name(capiChatRoom);
|
||||
unsigned int groupNumber = pbx_capi_chat_get_room_group(capiChatRoom);
|
||||
unsigned int groupUsers = pbx_capi_chat_get_room_group_members(capiChatRoom);
|
||||
unsigned int queueDepth = 0;
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
queueDepth = capi_DivaStreamingGetStreamInUse(i);
|
||||
#endif
|
||||
|
||||
ast_cli(fd, "%-17s %5u %7u %4d %11d\n",
|
||||
roomName, groupNumber, groupUsers, i->controller, queueDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
pbx_capi_unlock_chat_rooms();
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* do command capi info
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_info(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int i = 0, capi_num_controllers = pbx_capi_get_num_controllers();
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " info";
|
||||
e->usage = info_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
|
||||
if (argc != 2)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
ast_cli(fd, "%s www.chan-capi.org\n", pbx_capi_get_module_description());
|
||||
|
||||
for (i = 1; i <= capi_num_controllers; i++) {
|
||||
const struct cc_capi_controller *capiController = pbx_capi_get_controller(i);
|
||||
if (capiController != NULL) {
|
||||
ast_cli(fd, "Contr%d: %d B channels total, %d B channels free.%s\n",
|
||||
i, capiController->nbchannels,
|
||||
capiController->nfreebchannels,
|
||||
(capiController->used) ? "":" (unused)");
|
||||
}
|
||||
}
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* enable debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_do_debug(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " debug";
|
||||
e->usage = debug_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 2)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
capidebug = 1;
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Message Debugging Enabled\n");
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* disable debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_no_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_no_debug(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " no debug";
|
||||
e->usage = no_debug_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 3)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
capidebug = 0;
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Message Debugging Disabled\n");
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* enable QSIG debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_qsig_do_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_qsig_do_debug(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " qsig debug";
|
||||
e->usage = qsig_debug_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 3)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
capiqsigdebug = 1;
|
||||
ast_cli(fd, "QSIG Debugging Enabled\n");
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* disable QSIG debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_qsig_no_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_qsig_no_debug(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " qsig no debug";
|
||||
e->usage = qsig_no_debug_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 4)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
capiqsigdebug = 0;
|
||||
ast_cli(fd, "QSIG Debugging Disabled\n");
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* exec capi command
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_exec_capicommand(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_exec_capicommand(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int required_args = 4;
|
||||
int provided_args;
|
||||
const char* requiredChannelName = NULL;
|
||||
const char* chancapiCommand = NULL;
|
||||
int ret;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " exec";
|
||||
e->usage = show_exec_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE) {
|
||||
return NULL;
|
||||
}
|
||||
provided_args = a->argc;
|
||||
if (provided_args < required_args) {
|
||||
return CLI_SHOWUSAGE;
|
||||
}
|
||||
requiredChannelName = a->argv[2];
|
||||
chancapiCommand = a->argv[3];
|
||||
#else
|
||||
provided_args = argc;
|
||||
if (provided_args < required_args) {
|
||||
return RESULT_SHOWUSAGE;
|
||||
}
|
||||
requiredChannelName = argv[2];
|
||||
chancapiCommand = argv[3];
|
||||
#endif
|
||||
|
||||
ret = pbx_capi_management_capicommand(requiredChannelName, chancapiCommand);
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||
#else
|
||||
return ((ret == 0) ? RESULT_SUCCESS : RESULT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* exec capi command
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static char *pbxcli_capi_chat_manage_capicommand(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
static int pbxcli_capi_chat_manage_capicommand(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int required_args = 6;
|
||||
int provided_args;
|
||||
const char* roomName = NULL;
|
||||
const char* memberName = NULL;
|
||||
const char* chatCommand = NULL;
|
||||
const char* commandParameters = NULL;
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
const char * const *cli_argv;
|
||||
#elif (defined(CC_AST_HAS_VERSION_1_6) && !defined(CC_AST_HAS_VERSION_1_8))
|
||||
char **cli_argv;
|
||||
#else
|
||||
char * const *cli_argv;
|
||||
#endif
|
||||
int ret = -1;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " chat manage";
|
||||
e->usage = show_chat_manage_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE) {
|
||||
return NULL;
|
||||
}
|
||||
provided_args = a->argc;
|
||||
cli_argv = a->argv;
|
||||
if (provided_args < required_args) {
|
||||
return CLI_SHOWUSAGE;
|
||||
}
|
||||
#else
|
||||
provided_args = argc;
|
||||
cli_argv = argv;
|
||||
if (provided_args < required_args) {
|
||||
return RESULT_SHOWUSAGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
roomName = cli_argv[3];
|
||||
memberName = cli_argv[4];
|
||||
chatCommand = cli_argv[5];
|
||||
if (provided_args > required_args)
|
||||
commandParameters = cli_argv[6];
|
||||
|
||||
if (strcmp(chatCommand, "remove") == 0) {
|
||||
ret = pbx_capi_chat_remove_user (roomName, memberName);
|
||||
}
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||
#else
|
||||
return ((ret == 0) ? RESULT_SUCCESS : RESULT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* define commands
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static struct ast_cli_entry cc_cli_cmd[] = {
|
||||
AST_CLI_DEFINE(pbxcli_capi_info, CC_CLI_TEXT_INFO),
|
||||
AST_CLI_DEFINE(pbxcli_capi_show_channels, CC_CLI_TEXT_SHOW_CHANNELS),
|
||||
AST_CLI_DEFINE(pbxcli_capi_do_debug, CC_CLI_TEXT_DEBUG),
|
||||
AST_CLI_DEFINE(pbxcli_capi_no_debug, CC_CLI_TEXT_NO_DEBUG),
|
||||
AST_CLI_DEFINE(pbxcli_capi_qsig_do_debug, CC_CLI_TEXT_QSIG_DEBUG),
|
||||
AST_CLI_DEFINE(pbxcli_capi_qsig_no_debug, CC_CLI_TEXT_QSIG_NO_DEBUG),
|
||||
AST_CLI_DEFINE(pbxcli_capi_chatinfo, CC_CLI_TEXT_CHATINFO),
|
||||
#ifdef DIVA_STATUS
|
||||
AST_CLI_DEFINE(pbxcli_capi_ifc_status, CC_CLI_TEXT_IFC_STATUSINFO),
|
||||
#endif
|
||||
#ifdef DIVA_VERBOSE
|
||||
AST_CLI_DEFINE(pbxcli_capi_do_verbose, CC_CLI_TEXT_CAPI_DO_VERBOSE),
|
||||
AST_CLI_DEFINE(pbxcli_capi_no_verbose, CC_CLI_TEXT_CAPI_NO_VERBOSE),
|
||||
#endif
|
||||
AST_CLI_DEFINE(pbxcli_capi_show_resources, CC_CLI_TEXT_SHOW_RESOURCES),
|
||||
AST_CLI_DEFINE(pbxcli_capi_exec_capicommand, CC_CLI_TEXT_EXEC_CAPICOMMAND),
|
||||
AST_CLI_DEFINE(pbxcli_capi_chat_manage_capicommand, CC_CLI_TEXT_CHAT_MANAGE),
|
||||
AST_CLI_DEFINE(pbxcli_capi_show_bridges, CC_CLI_TEXT_SHOW_BRIDGES),
|
||||
};
|
||||
#else
|
||||
static struct ast_cli_entry cli_info =
|
||||
{ { CC_MESSAGE_NAME, "info", NULL }, pbxcli_capi_info, CC_CLI_TEXT_INFO, info_usage };
|
||||
static struct ast_cli_entry cli_show_channels =
|
||||
{ { CC_MESSAGE_NAME, "show", "channels", NULL }, pbxcli_capi_show_channels, CC_CLI_TEXT_SHOW_CHANNELS, show_channels_usage };
|
||||
static struct ast_cli_entry cli_debug =
|
||||
{ { CC_MESSAGE_NAME, "debug", NULL }, pbxcli_capi_do_debug, CC_CLI_TEXT_DEBUG, debug_usage };
|
||||
static struct ast_cli_entry cli_no_debug =
|
||||
{ { CC_MESSAGE_NAME, "no", "debug", NULL }, pbxcli_capi_no_debug, CC_CLI_TEXT_NO_DEBUG, no_debug_usage };
|
||||
static struct ast_cli_entry cli_qsig_debug =
|
||||
{ { CC_MESSAGE_NAME, "qsig", "debug", NULL }, pbxcli_capi_qsig_do_debug, CC_CLI_TEXT_QSIG_DEBUG, qsig_debug_usage };
|
||||
static struct ast_cli_entry cli_qsig_no_debug =
|
||||
{ { CC_MESSAGE_NAME, "qsig", "no", "debug", NULL }, pbxcli_capi_qsig_no_debug, CC_CLI_TEXT_QSIG_NO_DEBUG, qsig_no_debug_usage };
|
||||
static struct ast_cli_entry cli_chatinfo =
|
||||
{ { CC_MESSAGE_NAME, "chatinfo", NULL }, pbxcli_capi_chatinfo, CC_CLI_TEXT_CHATINFO, chatinfo_usage };
|
||||
#ifdef DIVA_STATUS
|
||||
static struct ast_cli_entry cli_ifcstate =
|
||||
{ { CC_MESSAGE_NAME, "ifcstate", NULL }, pbxcli_capi_ifc_status, CC_CLI_TEXT_IFC_STATUSINFO, diva_status_ifc_state_usage };
|
||||
#endif
|
||||
#ifdef DIVA_VERBOSE
|
||||
static struct ast_cli_entry cli_verbose =
|
||||
{ { CC_MESSAGE_NAME, "verbose", NULL }, pbxcli_capi_do_verbose, CC_CLI_TEXT_CAPI_DO_VERBOSE, capi_do_verbose_usage };
|
||||
static struct ast_cli_entry cli_no_verbose =
|
||||
{ { CC_MESSAGE_NAME, "no", "verbose", NULL }, pbxcli_capi_no_verbose, CC_CLI_TEXT_CAPI_NO_VERBOSE, capi_no_verbose_usage };
|
||||
#endif
|
||||
static struct ast_cli_entry cli_show_resources =
|
||||
{ { CC_MESSAGE_NAME, "show", "resources", NULL }, pbxcli_capi_show_resources, CC_CLI_TEXT_SHOW_RESOURCES, show_resources_usage };
|
||||
static struct ast_cli_entry cli_exec_capicommand =
|
||||
{ { CC_MESSAGE_NAME, "exec", NULL }, pbxcli_capi_exec_capicommand, CC_CLI_TEXT_CHAT_MANAGE, show_exec_usage };
|
||||
static struct ast_cli_entry cli_chat_manage =
|
||||
{ { CC_MESSAGE_NAME, "chat", "manage", NULL }, pbxcli_capi_chat_manage_capicommand, CC_CLI_TEXT_EXEC_CAPICOMMAND, show_chat_manage_usage };
|
||||
static struct ast_cli_entry cli_show_bridges =
|
||||
{ { CC_MESSAGE_NAME, "show", "bridges", NULL }, pbxcli_capi_show_bridges, CC_CLI_TEXT_SHOW_BRIDGES, show_bridges_usage };
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void pbx_capi_cli_register(void)
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
ast_cli_register_multiple(cc_cli_cmd, sizeof(cc_cli_cmd)/ sizeof(struct ast_cli_entry));
|
||||
#else
|
||||
ast_cli_register(&cli_info);
|
||||
ast_cli_register(&cli_show_channels);
|
||||
ast_cli_register(&cli_debug);
|
||||
ast_cli_register(&cli_no_debug);
|
||||
ast_cli_register(&cli_qsig_debug);
|
||||
ast_cli_register(&cli_qsig_no_debug);
|
||||
ast_cli_register(&cli_chatinfo);
|
||||
#ifdef DIVA_STATUS
|
||||
ast_cli_register(&cli_ifcstate);
|
||||
#endif
|
||||
#ifdef DIVA_VERBOSE
|
||||
ast_cli_register(&cli_verbose);
|
||||
ast_cli_register(&cli_no_verbose);
|
||||
#endif
|
||||
ast_cli_register(&cli_show_resources);
|
||||
ast_cli_register(&cli_exec_capicommand);
|
||||
ast_cli_register(&cli_chat_manage);
|
||||
ast_cli_register(&cli_show_bridges);
|
||||
#endif
|
||||
}
|
||||
|
||||
void pbx_capi_cli_unregister(void)
|
||||
{
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
ast_cli_unregister_multiple(cc_cli_cmd, sizeof(cc_cli_cmd)/ sizeof(struct ast_cli_entry));
|
||||
#else
|
||||
ast_cli_unregister(&cli_info);
|
||||
ast_cli_unregister(&cli_show_channels);
|
||||
ast_cli_unregister(&cli_debug);
|
||||
ast_cli_unregister(&cli_no_debug);
|
||||
ast_cli_unregister(&cli_qsig_debug);
|
||||
ast_cli_unregister(&cli_qsig_no_debug);
|
||||
ast_cli_unregister(&cli_chatinfo);
|
||||
#ifdef DIVA_STATUS
|
||||
ast_cli_unregister(&cli_ifcstate);
|
||||
#endif
|
||||
#ifdef DIVA_VERBOSE
|
||||
ast_cli_unregister(&cli_verbose);
|
||||
ast_cli_unregister(&cli_no_verbose);
|
||||
#endif
|
||||
ast_cli_unregister(&cli_show_resources);
|
||||
ast_cli_unregister(&cli_exec_capicommand);
|
||||
ast_cli_unregister(&cli_chat_manage);
|
||||
ast_cli_unregister(&cli_show_bridges);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* An implementation of Common ISDN API 2.0 for Asterisk
|
||||
*
|
||||
* Copyright (C) 2005-2010 Cytronics & Melware
|
||||
*
|
||||
* Armin Schindler <armin@melware.de>
|
||||
*
|
||||
* Reworked, but based on the work of
|
||||
* Copyright (C) 2002-2005 Junghanns.NET GmbH
|
||||
*
|
||||
* Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
|
||||
*
|
||||
* This program is free software and may be modified and
|
||||
* distributed under the terms of the GNU Public License.
|
||||
*/
|
||||
#ifndef __CC_CLI_IFC_H__
|
||||
#define __CC_CLI_IFC_H__
|
||||
|
||||
void pbx_capi_cli_register(void);
|
||||
void pbx_capi_cli_unregister(void);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -60,11 +60,11 @@ typedef struct _pbx_capi_voice_command {
|
|||
* LOCALS
|
||||
*/
|
||||
static const char* pbx_capi_voicecommand_digits = "1234567890ABCD*#";
|
||||
static int pbx_capi_command_nop (struct ast_channel *c, char *param);
|
||||
static pbx_capi_voice_command_t* pbx_capi_find_command (struct capi_pvt *i, const char* name);
|
||||
static pbx_capi_voice_command_t* pbx_capi_find_command_by_key (struct capi_pvt *i, const char* key);
|
||||
static pbx_capi_voice_command_t* pbx_capi_voicecommand_find_digit_command (diva_entity_queue_t* q, const char* digits, int length, int* info);
|
||||
static void pbx_capi_voicecommand_insert_command (diva_entity_queue_t* q, pbx_capi_voice_command_t* cmd);
|
||||
static int pbx_capi_command_nop(struct ast_channel *c, char *param);
|
||||
static pbx_capi_voice_command_t* pbx_capi_find_command(struct capi_pvt *i, const char* name);
|
||||
static pbx_capi_voice_command_t* pbx_capi_find_command_by_key(struct capi_pvt *i, const char* key);
|
||||
static pbx_capi_voice_command_t* pbx_capi_voicecommand_find_digit_command(diva_entity_queue_t* q, const char* digits, int length, int* info);
|
||||
static void pbx_capi_voicecommand_insert_command(diva_entity_queue_t* q, pbx_capi_voice_command_t* cmd);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -101,17 +101,18 @@ int pbx_capi_voicecommand(struct ast_channel *c, char *param)
|
|||
}
|
||||
|
||||
command[0] = param;
|
||||
command[1] = strchr (command[0], '|');
|
||||
command[1] = strchr(command[0], '|');
|
||||
|
||||
if (command[1] == 0) {
|
||||
/*
|
||||
* Remove command
|
||||
*/
|
||||
cc_mutex_lock(&i->lock);
|
||||
while ((cmd = pbx_capi_find_command (i, command[0])) != 0) {
|
||||
cc_verbose(2, 0, VERBOSE_PREFIX_4"%s: voicecommand:%s removed\n", i->vname, cmd->command_name);
|
||||
diva_q_remove (&i->channel_command_q, &cmd->link);
|
||||
free (cmd);
|
||||
while ((cmd = pbx_capi_find_command(i, command[0])) != 0) {
|
||||
cc_verbose(2, 0, VERBOSE_PREFIX_4"%s: voicecommand:%s removed\n",
|
||||
i->vname, cmd->command_name);
|
||||
diva_q_remove(&i->channel_command_q, &cmd->link);
|
||||
ast_free (cmd);
|
||||
}
|
||||
cc_mutex_unlock(&i->lock);
|
||||
} else {
|
||||
|
@ -148,7 +149,7 @@ int pbx_capi_voicecommand(struct ast_channel *c, char *param)
|
|||
}
|
||||
}
|
||||
|
||||
cmd = malloc(sizeof(*cmd));
|
||||
cmd = ast_malloc(sizeof(*cmd));
|
||||
if (cmd == NULL) {
|
||||
cc_log(LOG_WARNING, CC_MESSAGE_NAME " can not allocate memory for voice command\n");
|
||||
return -1;
|
||||
|
@ -166,7 +167,7 @@ int pbx_capi_voicecommand(struct ast_channel *c, char *param)
|
|||
cmd->channel_command_digits[length] = 0;
|
||||
cmd->length = length;
|
||||
|
||||
cmd->pbx_capi_command = pbx_capi_lockup_command_by_name (cmd->command_name);
|
||||
cmd->pbx_capi_command = pbx_capi_lockup_command_by_name(cmd->command_name);
|
||||
if ( cmd->pbx_capi_command == 0) {
|
||||
cmd->pbx_capi_command = pbx_capi_command_nop; /* accept unknown commands for compatibility reason */
|
||||
}
|
||||
|
@ -180,14 +181,14 @@ int pbx_capi_voicecommand(struct ast_channel *c, char *param)
|
|||
pbx_capi_voice_command_t* present_cmd;
|
||||
|
||||
cc_mutex_lock(&i->lock);
|
||||
if ((present_cmd = pbx_capi_find_command_by_key (i, cmd->command_name)) != 0) {
|
||||
diva_q_remove (&i->channel_command_q, &present_cmd->link);
|
||||
if ((present_cmd = pbx_capi_find_command_by_key(i, cmd->command_name)) != 0) {
|
||||
diva_q_remove(&i->channel_command_q, &present_cmd->link);
|
||||
}
|
||||
pbx_capi_voicecommand_insert_command (&i->channel_command_q, cmd);
|
||||
pbx_capi_voicecommand_insert_command(&i->channel_command_q, cmd);
|
||||
cc_mutex_unlock(&i->lock);
|
||||
|
||||
if (present_cmd != 0) {
|
||||
free (present_cmd);
|
||||
ast_free (present_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ int pbx_capi_voicecommand_cleanup(struct capi_pvt *i)
|
|||
|
||||
while ((link = diva_q_get_head(&i->channel_command_q)) != NULL) {
|
||||
diva_q_remove(&i->channel_command_q, link);
|
||||
free(link);
|
||||
ast_free(link);
|
||||
}
|
||||
|
||||
i->channel_command_digit = 0;
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
#include "chan_capi_devstate.h"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
enum ast_device_state
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
pbx_capi_chat_room_state(const char *data);
|
||||
|
||||
static int capiChatProviderRegistered;
|
||||
|
||||
void pbx_capi_register_device_state_providers(void)
|
||||
{
|
||||
int i, capi_num_controllers;
|
||||
|
||||
capiChatProviderRegistered = (ast_devstate_prov_add("Capichat", pbx_capi_chat_room_state) == 0);
|
||||
|
||||
/*
|
||||
Set initial device state for all supported interface
|
||||
*/
|
||||
for (i = 1, capi_num_controllers = pbx_capi_get_num_controllers();
|
||||
i <= capi_num_controllers;
|
||||
i++) {
|
||||
const struct cc_capi_controller *capiController = pbx_capi_get_controller(i);
|
||||
|
||||
if (capiController != NULL) {
|
||||
pbx_capi_ifc_state_event(capiController, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pbx_capi_unregister_device_state_providers(void)
|
||||
{
|
||||
if (capiChatProviderRegistered != 0) {
|
||||
ast_devstate_prov_del("Capichat");
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Read conference room state
|
||||
*/
|
||||
static
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
enum ast_device_state
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
pbx_capi_chat_room_state(const char *data)
|
||||
{
|
||||
const struct capichat_s *room;
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
enum ast_device_state ret = AST_DEVICE_NOT_INUSE;
|
||||
#else
|
||||
int ret = AST_DEVICE_NOT_INUSE;
|
||||
#endif
|
||||
|
||||
if (data == 0)
|
||||
return AST_DEVICE_INVALID;
|
||||
|
||||
pbx_capi_lock_chat_rooms();
|
||||
for (room = pbx_capi_chat_get_room_c(NULL);
|
||||
room != 0;
|
||||
room = pbx_capi_chat_get_room_c(room)) {
|
||||
if (strcmp(data, pbx_capi_chat_get_room_name(room)) == 0) {
|
||||
ret = AST_DEVICE_INUSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pbx_capi_unlock_chat_rooms();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Conference room state change
|
||||
*/
|
||||
void pbx_capi_chat_room_state_event(const char* roomName, int inUse)
|
||||
{
|
||||
if (capiChatProviderRegistered != 0) {
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
ast_devstate_changed((inUse != 0) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE, "capichat:%s", roomName);
|
||||
#else
|
||||
ast_device_state_changed("capichat:%s", roomName);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void pbx_capi_ifc_state_event(const struct cc_capi_controller* capiController, int channelsChanged)
|
||||
{
|
||||
if ((channelsChanged == 0) ||
|
||||
(capiController->nbchannels == capiController->nfreebchannels) ||
|
||||
(capiController->nfreebchannels == 0) ||
|
||||
((capiController->nfreebchannels < capiController->nfreebchannelsHardThr) &&
|
||||
(capiController->nfreebchannels - channelsChanged >= capiController->nfreebchannelsHardThr)) ||
|
||||
((capiController->nfreebchannels >= capiController->nfreebchannelsHardThr) &&
|
||||
(capiController->nfreebchannels - channelsChanged < capiController->nfreebchannelsHardThr))) {
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
ast_devstate_changed(AST_DEVICE_UNKNOWN, CC_MESSAGE_BIGNAME"/I%d/congestion", capiController->controller);
|
||||
#else
|
||||
ast_device_state_changed (CC_MESSAGE_BIGNAME"/I%d/congestion", capiController->controller);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __CC_DEVICE_STATE_PROVIDER_INTERFACE_H__
|
||||
#define __CC_DEVICE_STATE_PROVIDER_INTERFACE_H__
|
||||
|
||||
void pbx_capi_register_device_state_providers(void);
|
||||
void pbx_capi_unregister_device_state_providers(void);
|
||||
void pbx_capi_chat_room_state_event(const char* roomName, int inUse);
|
||||
void pbx_capi_ifc_state_event(const struct cc_capi_controller* capiController, int channelsChanged);
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int pbx_capi_get_all_locks (struct capi_pvt *i, struct ast_channel** usedChannel);
|
||||
|
||||
/*!
|
||||
\brief Execute any capicommand
|
||||
|
||||
\note Called from CLI or from AMI context
|
||||
*/
|
||||
int pbx_capi_management_capicommand(const char *requiredChannelName, const char *chancapiCommand) {
|
||||
int ifc_type, retry_search, search_loops;
|
||||
struct capi_pvt *i;
|
||||
struct {
|
||||
struct capi_pvt *head;
|
||||
void (*lock_proc)(void);
|
||||
void (*unlock_proc)(void);
|
||||
} data[2];
|
||||
|
||||
data[0].head = capi_iflist;
|
||||
data[0].lock_proc = pbx_capi_lock_interfaces;
|
||||
data[0].unlock_proc = pbx_capi_unlock_interfaces;
|
||||
data[1].head = (struct capi_pvt*)pbx_capi_get_nulliflist();
|
||||
data[1].lock_proc = pbx_capi_nulliflist_lock;
|
||||
data[1].unlock_proc = pbx_capi_nulliflist_unlock;
|
||||
|
||||
if (ast_strlen_zero(requiredChannelName)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(chancapiCommand)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (strcmp(requiredChannelName, "none") == 0) {
|
||||
int ret = (pbx_capi_cli_exec_capicommand(NULL, chancapiCommand) == 0) ? 0 : -1;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
for (ifc_type = 0; ifc_type < sizeof(data)/sizeof(data[0]); ifc_type++) {
|
||||
search_loops = 10;
|
||||
do {
|
||||
data[ifc_type].lock_proc();
|
||||
for (i = data[ifc_type].head, retry_search = 0; i != 0; i = i->next) {
|
||||
struct ast_channel* c = NULL;
|
||||
|
||||
if ((i->used == 0) || ((i->channeltype != CAPI_CHANNELTYPE_B) &&
|
||||
(i->channeltype != CAPI_CHANNELTYPE_NULL)))
|
||||
continue;
|
||||
if (i->data_plci != 0)
|
||||
continue;
|
||||
|
||||
if (pbx_capi_get_all_locks (i, &c) != 0) {
|
||||
retry_search = 1;
|
||||
break;
|
||||
}
|
||||
if ((!ast_strlen_zero(c->name) && (strcmp(requiredChannelName, c->name) == 0)) ||
|
||||
strcmp(requiredChannelName, i->vname) == 0) {
|
||||
struct ast_channel* usedChannel = c;
|
||||
int ret;
|
||||
|
||||
data[ifc_type].unlock_proc();
|
||||
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_NULL) {
|
||||
ret = (pbx_capi_cli_exec_capicommand(usedChannel, chancapiCommand) == 0) ? 0 : -1;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock(c);
|
||||
} else {
|
||||
ast_channel_unlock(c);
|
||||
ret = (pbx_capi_cli_exec_capicommand(usedChannel, chancapiCommand) == 0) ? 0 : -1;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
cc_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock(c);
|
||||
}
|
||||
data[ifc_type].unlock_proc();
|
||||
if (retry_search != 0) {
|
||||
usleep (100);
|
||||
}
|
||||
} while((retry_search != 0) && (search_loops-- > 0));
|
||||
}
|
||||
|
||||
return -4;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Try to take all locks. Called with false lock order
|
||||
* one of the list locks (iflock or nullif_lock) taken
|
||||
* Used by CLI/AMI
|
||||
*/
|
||||
static int pbx_capi_get_all_locks (struct capi_pvt *i, struct ast_channel** usedChannel)
|
||||
{
|
||||
struct ast_channel* c = (i->channeltype != CAPI_CHANNELTYPE_NULL) ? i->owner : i->used;
|
||||
if (c != 0) {
|
||||
if (ast_channel_trylock(c) == 0) {
|
||||
if (ast_mutex_trylock(&i->lock) == 0) {
|
||||
struct ast_channel* cref = (i->channeltype != CAPI_CHANNELTYPE_NULL) ? i->owner : i->used;
|
||||
if (cref == c) {
|
||||
*usedChannel = c;
|
||||
return (0);
|
||||
} else {
|
||||
ast_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
} else {
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __CC_MANAGEMENT_COMMON_INTERFACE_H__
|
||||
#define __CC_MANAGEMENT_COMMON_INTERFACE_H__
|
||||
|
||||
|
||||
int pbx_capi_management_capicommand(const char *requiredChannelName, const char *chancapiCommand);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,532 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
#include <asterisk/event.h>
|
||||
#endif
|
||||
#include "chan_capi_mwi.h"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static unsigned char* time2X208(time_t t);
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
static void pbx_capi_mwi_event(const struct ast_event *event, void *userdata);
|
||||
#endif
|
||||
|
||||
/*
|
||||
MWI command parameters of pbx_capi_mwi
|
||||
*/
|
||||
typedef enum _mwiAddSubscribtionParams {
|
||||
mwiAddSubscribtionController = 1,
|
||||
mwiAddSubscribtionReceivingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiAddSubscribtionReceivingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiAddSubscribtionReceivingUserNumber_PresentationAndScreening,
|
||||
mwiAddSubscribtionReceivingUserNumber,
|
||||
mwiAddSubscribtionControllingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiAddSubscribtionControllingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiAddSubscribtionControllingUserNumber_PresentationAndScreening,
|
||||
mwiAddSubscribtionControllingUserNumber,
|
||||
mwiAddSubscribtionControllingUserProvidedNumber_TypeOfFacilityPartyNumber,
|
||||
mwiAddSubscribtionControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiAddSubscribtionControllingUserProvidedNumber_PresentationAndScreening,
|
||||
mwiAddSubscribtionControllingUserProvidedNumber,
|
||||
mwiAddSubscribtionMax
|
||||
} mwiAddSubscribtionParams_t;
|
||||
|
||||
typedef enum _mwiRemoveSubscribtionParam {
|
||||
mwiRemoveSubscribtionController = 1,
|
||||
mwiRemoveSubscribtionReceivingUserNumber,
|
||||
mwiRemoveSubscribtionMax
|
||||
} mwiRemoveSubscribtionParam_t;
|
||||
|
||||
typedef enum _mwiXmitActivateParams {
|
||||
mwiXmitActivate = 1,
|
||||
mwiXmitActivateController,
|
||||
mwiXmitActivateBasicService,
|
||||
mwiXmitActivateNumberOfMessages,
|
||||
mwiXmitActivateMessageStatus,
|
||||
mwiXmitActivateMessageReference,
|
||||
mwiXmitActivateInvocationMode,
|
||||
mwiXmitActivateReceivingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiXmitActivateReceivingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiXmitActivateReceivingUserNumber_PresentationAndScreening,
|
||||
mwiXmitActivateReceivingUserNumber,
|
||||
mwiXmitActivateControllingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiXmitActivateControllingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiXmitActivateControllingUserNumber_PresentationAndScreening,
|
||||
mwiXmitActivateControllingUserNumber,
|
||||
mwiXmitActivateControllingUserProvidedNumber_TypeOfFacilityPartyNumber,
|
||||
mwiXmitActivateControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiXmitActivateControllingUserProvidedNumber_PresentationAndScreening,
|
||||
mwiXmitActivateControllingUserProvidedNumber,
|
||||
mwiXmitActivatesMax
|
||||
} mwiXmitActivateParams_t;
|
||||
|
||||
typedef enum _mwiXmitDeactivateParams {
|
||||
mwiXmitDeactivate = 1,
|
||||
mwiXmitDeactivateController,
|
||||
mwiXmitDeactivateBasicService,
|
||||
mwiXmitDeactivateInvocationMode,
|
||||
mwiXmitDeactivateReceivingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiXmitDeactivateReceivingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiXmitDeactivateReceivingUserNumber_PresentationAndScreening,
|
||||
mwiXmitDeactivateReceivingUserNumber,
|
||||
mwiXmitDeactivateControllingUserNumber_TypeOfFacilityPartyNumber,
|
||||
mwiXmitDeactivateControllingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
mwiXmitDeactivateControllingUserNumber_PresentationAndScreening,
|
||||
mwiXmitDeactivateControllingUserNumber,
|
||||
mwiXmitDeactivateMax
|
||||
} mwiXmitDeactivateParams_t;
|
||||
|
||||
/*
|
||||
add|controller|fpn|ton|pres|receivingUserNumber|fpn|ton|pres|controllingUserNumber|fpn|ton|pres|controllingUserProvidedNumber
|
||||
remove|conntroller|receivingUserNumber
|
||||
xmit|activate|controller|basicService|numberOfMessages|messageStatus|messageReference|invocationMode|
|
||||
fpn|ton|pres|receivingUserNumber|fpn|ton|pres|controllingUserNumber|fpn|ton|pres|controllingUserProvidedNumber
|
||||
xmit|deactivate|controller|basicService|invocationMode|fpn|ton|pres|receivingUserNumber|fpn|ton|pres|controllingUserNumber
|
||||
|
||||
add - add MWI subscription
|
||||
remoce - remove MWI subscription
|
||||
xmit - xmit MWI activate or deactivate
|
||||
*/
|
||||
int pbx_capi_mwi(struct ast_channel *c, char *info)
|
||||
{
|
||||
const char* params[MAX((MAX(mwiAddSubscribtionMax, mwiXmitActivatesMax)),(MAX(mwiRemoveSubscribtionMax, mwiXmitDeactivateMax)))];
|
||||
int ret = -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(params)/sizeof(params[0]); i++) {
|
||||
params[i] = strsep (&info, COMMANDSEPARATOR);
|
||||
}
|
||||
|
||||
if (params[0] == NULL)
|
||||
return (-1);
|
||||
if (strcmp(params[0], "add") == 0) {
|
||||
|
||||
} else if (strcmp (params[0], "remove") == 0) {
|
||||
|
||||
} else if (strcmp (params[0], "xmit") == 0) {
|
||||
if (strcmp (params[mwiXmitActivate], "activate") == 0) {
|
||||
int unit;
|
||||
|
||||
if (params[mwiXmitActivateController] != 0 && params[mwiXmitActivateController][0] != 0) {
|
||||
unit = atoi(params[mwiXmitActivateController]);
|
||||
|
||||
} else {
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
|
||||
unit = (i != 0) ? i->controller : 0;
|
||||
}
|
||||
|
||||
if (pbx_capi_get_controller(unit) != 0 && params[mwiXmitActivateReceivingUserNumber] != 0) {
|
||||
unsigned short basicService = params[mwiXmitActivateBasicService] != 0 ? (unsigned short)atoi(params[mwiXmitActivateBasicService]) : 1;
|
||||
unsigned short numberOfMessages = params[mwiXmitActivateNumberOfMessages] != 0 ? (unsigned int)atoi(params[mwiXmitActivateNumberOfMessages]) : 1;
|
||||
unsigned short messageStatus = params[mwiXmitActivateMessageStatus] != 0 ? (unsigned short)atoi(params[mwiXmitActivateMessageStatus]) : 0;
|
||||
unsigned short messageReference = params[mwiXmitActivateMessageReference] != 0 ? (unsigned short)atoi(params[mwiXmitActivateMessageReference]) : 0;
|
||||
unsigned short invocationMode = params[mwiXmitActivateInvocationMode] != 0 ? (unsigned short)atoi(params[mwiXmitActivateInvocationMode]) : 2;
|
||||
unsigned char ReceivingUserNumber_TypeOfFacilityPartyNumber = params[mwiXmitActivateReceivingUserNumber_TypeOfFacilityPartyNumber] != 0 ?
|
||||
(unsigned char)atoi(params[mwiXmitActivateReceivingUserNumber_TypeOfFacilityPartyNumber]) : 0;
|
||||
unsigned char ReceivingUserNumber_TypeOfNumberAndNumberingPlan = params[mwiXmitActivateReceivingUserNumber_TypeOfNumberAndNumberingPlan] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateReceivingUserNumber_TypeOfNumberAndNumberingPlan])) & ~0x80) : 0;
|
||||
unsigned char ReceivingUserNumber_PresentationAndScreening = params[mwiXmitActivateReceivingUserNumber_PresentationAndScreening] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateReceivingUserNumber_PresentationAndScreening])) & ~0x80) : 0;
|
||||
const char* ReceivingUserNumber = params[mwiXmitActivateReceivingUserNumber];
|
||||
unsigned char ControllingUserNumber_TypeOfFacilityPartyNumber = params[mwiXmitActivateControllingUserNumber_TypeOfFacilityPartyNumber] != 0 ?
|
||||
(unsigned char)atoi(params[mwiXmitActivateControllingUserNumber_TypeOfFacilityPartyNumber]) : 0;
|
||||
unsigned char ControllingUserNumber_TypeOfNumberAndNumberingPlan = params[mwiXmitActivateControllingUserNumber_TypeOfNumberAndNumberingPlan] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateControllingUserNumber_TypeOfNumberAndNumberingPlan])) & ~0x80) : 0;
|
||||
unsigned char ControllingUserNumber_PresentationAndScreening = params[mwiXmitActivateControllingUserNumber_PresentationAndScreening] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateControllingUserNumber_PresentationAndScreening])) & ~0x80) : 0;
|
||||
const char* ControllingUserNumber = params[mwiXmitActivateControllingUserNumber];
|
||||
unsigned char ControllingUserProvidedNumber_TypeOfFacilityPartyNumber = params[mwiXmitActivateControllingUserProvidedNumber_TypeOfFacilityPartyNumber] != 0 ?
|
||||
(unsigned char)atoi(params[mwiXmitActivateControllingUserProvidedNumber_TypeOfFacilityPartyNumber]) : 0;
|
||||
unsigned char ControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan = params[mwiXmitActivateControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan])) & ~0x80) : 0;
|
||||
unsigned char ControllingUserProvidedNumber_PresentationAndScreening = params[mwiXmitActivateControllingUserProvidedNumber_PresentationAndScreening] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitActivateControllingUserProvidedNumber_PresentationAndScreening])) & ~0x80) : 0;
|
||||
const char* ControllingUserProvidedNumber = params[mwiXmitActivateControllingUserProvidedNumber];
|
||||
unsigned char *facilityReceivingUserNumber = pbx_capi_build_facility_number (ReceivingUserNumber_TypeOfFacilityPartyNumber,
|
||||
ReceivingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
ReceivingUserNumber_PresentationAndScreening,
|
||||
ReceivingUserNumber);
|
||||
unsigned char *facilityControllingUserNumber = pbx_capi_build_facility_number (ControllingUserNumber_TypeOfFacilityPartyNumber,
|
||||
ControllingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
ControllingUserNumber_PresentationAndScreening,
|
||||
ControllingUserNumber);
|
||||
unsigned char *facilityControllingUserProvidedNumber = pbx_capi_build_facility_number (ControllingUserProvidedNumber_TypeOfFacilityPartyNumber,
|
||||
ControllingUserProvidedNumber_TypeOfNumberAndNumberingPlan,
|
||||
ControllingUserProvidedNumber_PresentationAndScreening,
|
||||
ControllingUserProvidedNumber);
|
||||
unsigned char* t = time2X208(time(NULL));
|
||||
|
||||
ret = pbx_capi_xmit_mwi(pbx_capi_get_controller(unit),
|
||||
basicService,
|
||||
numberOfMessages,
|
||||
messageStatus,
|
||||
messageReference,
|
||||
invocationMode,
|
||||
facilityReceivingUserNumber,
|
||||
facilityControllingUserNumber,
|
||||
facilityControllingUserProvidedNumber,
|
||||
t);
|
||||
|
||||
ast_free(facilityReceivingUserNumber);
|
||||
ast_free(facilityControllingUserNumber);
|
||||
ast_free(facilityControllingUserProvidedNumber);
|
||||
ast_free(t);
|
||||
}
|
||||
} else if (strcmp (params[mwiXmitDeactivate], "deactivate") == 0) {
|
||||
int unit;
|
||||
|
||||
if (params[mwiXmitDeactivateController] != 0 && params[mwiXmitDeactivateController][0] != 0) {
|
||||
unit = atoi(params[mwiXmitDeactivateController]);
|
||||
|
||||
} else {
|
||||
struct capi_pvt *i = CC_CHANNEL_PVT(c);
|
||||
|
||||
unit = (i != 0) ? i->controller : 0;
|
||||
}
|
||||
if (pbx_capi_get_controller(unit) != 0 && params[mwiXmitDeactivateReceivingUserNumber] != 0) {
|
||||
unsigned short basicService = params[mwiXmitDeactivateBasicService] != 0 ? (unsigned short)atoi(params[mwiXmitDeactivateBasicService]) : 1;
|
||||
unsigned short invocationMode = params[mwiXmitDeactivateInvocationMode] != 0 ? (unsigned short)atoi(params[mwiXmitDeactivateInvocationMode]) : 2;
|
||||
unsigned char ReceivingUserNumber_TypeOfFacilityPartyNumber = params[mwiXmitDeactivateReceivingUserNumber_TypeOfFacilityPartyNumber] != 0 ?
|
||||
(unsigned char)atoi(params[mwiXmitDeactivateReceivingUserNumber_TypeOfFacilityPartyNumber]) : 0;
|
||||
unsigned char ReceivingUserNumber_TypeOfNumberAndNumberingPlan = params[mwiXmitDeactivateReceivingUserNumber_TypeOfNumberAndNumberingPlan] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitDeactivateReceivingUserNumber_TypeOfNumberAndNumberingPlan])) & ~0x80) : 0;
|
||||
unsigned char ReceivingUserNumber_PresentationAndScreening = params[mwiXmitDeactivateReceivingUserNumber_PresentationAndScreening] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitDeactivateReceivingUserNumber_PresentationAndScreening])) & ~0x80) : 0;
|
||||
const char* ReceivingUserNumber = params[mwiXmitDeactivateReceivingUserNumber];
|
||||
unsigned char ControllingUserNumber_TypeOfFacilityPartyNumber = params[mwiXmitDeactivateControllingUserNumber_TypeOfFacilityPartyNumber] != 0 ?
|
||||
(unsigned char)atoi(params[mwiXmitDeactivateControllingUserNumber_TypeOfFacilityPartyNumber]) : 0;
|
||||
unsigned char ControllingUserNumber_TypeOfNumberAndNumberingPlan = params[mwiXmitDeactivateControllingUserNumber_TypeOfNumberAndNumberingPlan] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitDeactivateControllingUserNumber_TypeOfNumberAndNumberingPlan])) & ~0x80) : 0;
|
||||
unsigned char ControllingUserNumber_PresentationAndScreening = params[mwiXmitDeactivateControllingUserNumber_PresentationAndScreening] != 0 ?
|
||||
(((unsigned char)atoi(params[mwiXmitDeactivateControllingUserNumber_PresentationAndScreening])) & ~0x80) : 0;
|
||||
const char* ControllingUserNumber = params[mwiXmitDeactivateControllingUserNumber];
|
||||
unsigned char *facilityReceivingUserNumber = pbx_capi_build_facility_number (ReceivingUserNumber_TypeOfFacilityPartyNumber,
|
||||
ReceivingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
ReceivingUserNumber_PresentationAndScreening,
|
||||
ReceivingUserNumber);
|
||||
unsigned char *facilityControllingUserNumber = pbx_capi_build_facility_number (ControllingUserNumber_TypeOfFacilityPartyNumber,
|
||||
ControllingUserNumber_TypeOfNumberAndNumberingPlan,
|
||||
ControllingUserNumber_PresentationAndScreening,
|
||||
ControllingUserNumber);
|
||||
|
||||
ret = pbx_capi_xmit_mwi_deactivate(pbx_capi_get_controller(unit),
|
||||
basicService, invocationMode, facilityReceivingUserNumber, facilityControllingUserNumber);
|
||||
|
||||
ast_free (facilityReceivingUserNumber);
|
||||
ast_free (facilityControllingUserNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int pbx_capi_xmit_mwi(
|
||||
const struct cc_capi_controller *controller,
|
||||
unsigned short basicService,
|
||||
unsigned int numberOfMessages,
|
||||
unsigned short messageStatus,
|
||||
unsigned short messageReference,
|
||||
unsigned short invocationMode,
|
||||
const unsigned char* receivingUserNumber,
|
||||
const unsigned char* controllingUserNumber,
|
||||
const unsigned char* controllingUserProvidedNumber,
|
||||
const unsigned char* timeX208)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cword messageNumber = get_capi_MessageNumber();
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_FACILITY_REQ, controller->controller, messageNumber,
|
||||
"w(w(wdwwwssssd))",
|
||||
0x0003, /* Suppl. Service */
|
||||
0x0013, /* MWI Activate */
|
||||
basicService, /* Basic Service */
|
||||
numberOfMessages, /* Number of messages */
|
||||
messageStatus, /* Added messages */
|
||||
messageReference, /* Message reference */
|
||||
invocationMode, /* Invocation mode */
|
||||
receivingUserNumber, /* Receiving user number */
|
||||
controllingUserNumber, /* Controlling user number */
|
||||
controllingUserProvidedNumber, /* Controlling user provided number */
|
||||
timeX208, /* time */
|
||||
messageNumber);
|
||||
|
||||
return ((error == CapiNoError) ? 0 : -1);
|
||||
}
|
||||
|
||||
int pbx_capi_xmit_mwi_deactivate(
|
||||
const struct cc_capi_controller *controller,
|
||||
unsigned short basicService,
|
||||
unsigned short invocationMode,
|
||||
const unsigned char* receivingUserNumber,
|
||||
const unsigned char* controllingUserNumber)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
_cword messageNumber = get_capi_MessageNumber();
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_FACILITY_REQ, controller->controller, messageNumber,
|
||||
"w(w(wwss))",
|
||||
0x0003, /* Suppl. Service */
|
||||
0x0014, /* MWI Activate */
|
||||
basicService, /* Basic Service */
|
||||
invocationMode, /* Invocation mode */
|
||||
receivingUserNumber, /* Receiving user number */
|
||||
controllingUserNumber /* Controlling user number */);
|
||||
|
||||
return ((error == CapiNoError) ? 0 : -1);
|
||||
}
|
||||
|
||||
static unsigned char* time2X208 (time_t t) {
|
||||
unsigned char* ret = 0;
|
||||
#if defined(CC_AST_HAS_VERSION_1_6)
|
||||
unsigned char tX208[] = { 0x0c, 0x32, 0x30, 0x30, 0x31, 0x30, 0x35, 0x31, 0x31, 0x30, 0x39, 0x33, 0x36, 0x00 };
|
||||
struct timeval tv = {
|
||||
.tv_sec = t,
|
||||
};
|
||||
struct ast_tm tm;
|
||||
|
||||
ast_localtime(&tv, &tm, "utc");
|
||||
ast_strftime((char*)&tX208[1], sizeof(tX208)-1, "%Y%d%m%H%M", &tm);
|
||||
|
||||
ret = ast_malloc (sizeof(tX208));
|
||||
if (ret != 0)
|
||||
memcpy (ret, tX208, sizeof(tX208));
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
static void pbx_capi_mwi_event(const struct ast_event *event, void *userdata)
|
||||
{
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion = userdata;
|
||||
/* const char *mbox_context; */
|
||||
const char *mbox_number;
|
||||
int num_messages, num_old_messages;
|
||||
unsigned char* t;
|
||||
int ret;
|
||||
|
||||
mbox_number = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
|
||||
if (ast_strlen_zero(mbox_number)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
mbox_context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
|
||||
if (ast_strlen_zero(mbox_context)) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
|
||||
num_old_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
|
||||
|
||||
t = time2X208 (time(NULL));
|
||||
|
||||
cc_verbose (4, 0, "CAPI%d MWI event for '%s@%s' %d messages\n",
|
||||
mwiSubscribtion->controller->controller,
|
||||
mwiSubscribtion->mailboxNumber+4,
|
||||
mwiSubscribtion->mailboxContext,
|
||||
num_messages);
|
||||
|
||||
if ((num_messages != 0) || (num_old_messages != 0)) {
|
||||
ret = pbx_capi_xmit_mwi(mwiSubscribtion->controller,
|
||||
mwiSubscribtion->basicService,
|
||||
num_messages,
|
||||
0,
|
||||
0,
|
||||
mwiSubscribtion->invocationMode,
|
||||
mwiSubscribtion->mailboxNumber,
|
||||
mwiSubscribtion->controllingUserNumber,
|
||||
mwiSubscribtion->controllingUserProvidedNumber,
|
||||
t);
|
||||
} else {
|
||||
ret = pbx_capi_xmit_mwi_deactivate(mwiSubscribtion->controller,
|
||||
mwiSubscribtion->basicService,
|
||||
mwiSubscribtion->invocationMode,
|
||||
mwiSubscribtion->mailboxNumber,
|
||||
mwiSubscribtion->controllingUserNumber);
|
||||
}
|
||||
|
||||
ast_free(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
void pbx_capi_register_mwi(struct cc_capi_controller *controller)
|
||||
{
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion;
|
||||
|
||||
AST_LIST_TRAVERSE(&controller->mwiSubscribtions, mwiSubscribtion, link) {
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
mwiSubscribtion->mwiSubscribtion = ast_event_subscribe(AST_EVENT_MWI, pbx_capi_mwi_event,
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
"CHAN_CAPI mbox event",
|
||||
#endif
|
||||
mwiSubscribtion,
|
||||
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, &mwiSubscribtion->mailboxNumber[4],
|
||||
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mwiSubscribtion->mailboxContext,
|
||||
AST_EVENT_IE_END);
|
||||
#endif
|
||||
if (mwiSubscribtion->mwiSubscribtion == 0) {
|
||||
cc_log(LOG_WARNING, "CAPI%d failed to activate MWI subscribtion for '%s@%s'\n",
|
||||
mwiSubscribtion->controller->controller,
|
||||
&mwiSubscribtion->mailboxNumber[4],
|
||||
mwiSubscribtion->mailboxContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pbx_capi_refresh_mwi(struct cc_capi_controller *controller)
|
||||
{
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion;
|
||||
|
||||
AST_LIST_TRAVERSE(&controller->mwiSubscribtions, mwiSubscribtion, link) {
|
||||
if (mwiSubscribtion->mwiSubscribtion != 0) {
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
struct ast_event *event = ast_event_get_cached(AST_EVENT_MWI,
|
||||
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, &mwiSubscribtion->mailboxNumber[4],
|
||||
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mwiSubscribtion->mailboxContext,
|
||||
AST_EVENT_IE_END);
|
||||
if (event != 0) {
|
||||
pbx_capi_mwi_event(event, mwiSubscribtion);
|
||||
ast_event_destroy(event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pbx_capi_unregister_mwi(struct cc_capi_controller *controller)
|
||||
{
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion;
|
||||
|
||||
AST_LIST_TRAVERSE(&controller->mwiSubscribtions, mwiSubscribtion, link) {
|
||||
if (mwiSubscribtion->mwiSubscribtion != 0) {
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
ast_event_unsubscribe(mwiSubscribtion->mwiSubscribtion);
|
||||
#endif
|
||||
mwiSubscribtion->mwiSubscribtion = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pbx_capi_cleanup_mwi(struct cc_capi_controller *controller)
|
||||
{
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion;
|
||||
|
||||
pbx_capi_unregister_mwi(controller);
|
||||
|
||||
while ((mwiSubscribtion = AST_LIST_REMOVE_HEAD(&controller->mwiSubscribtions, link)) != 0) {
|
||||
ast_free (mwiSubscribtion->mailboxNumber);
|
||||
ast_free (mwiSubscribtion->mailboxContext);
|
||||
ast_free (mwiSubscribtion->controllingUserNumber);
|
||||
ast_free (mwiSubscribtion->controllingUserProvidedNumber);
|
||||
ast_free (mwiSubscribtion);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* pbx_capi_build_facility_number(
|
||||
unsigned char mwifacptynrtype,
|
||||
unsigned char mwifacptynrton,
|
||||
unsigned char mwifacptynrpres,
|
||||
const char* number)
|
||||
{
|
||||
unsigned char* fnr = 0;
|
||||
|
||||
if (number != 0) {
|
||||
fnr = ast_malloc (strlen(number)+7);
|
||||
if (fnr != 0) {
|
||||
fnr[0] = strlen(number) + 3;
|
||||
fnr[1] = mwifacptynrtype;
|
||||
fnr[2] = mwifacptynrton;
|
||||
fnr[3] = mwifacptynrpres | 0x80;
|
||||
strcpy((char*)&fnr[4], number);
|
||||
}
|
||||
}
|
||||
|
||||
return (fnr);
|
||||
}
|
||||
|
||||
/*
|
||||
Init MWI subscriptions
|
||||
*/
|
||||
void pbx_capi_init_mwi_server (
|
||||
struct cc_capi_controller *mwiController,
|
||||
const struct cc_capi_conf *conf) {
|
||||
|
||||
if ((mwiController != 0) && (conf->mwimailbox != 0)) {
|
||||
char* mailboxList = conf->mwimailbox;
|
||||
char* mailboxMember;
|
||||
|
||||
while ((mailboxMember = strsep (&mailboxList, ",")) != 0) {
|
||||
/*
|
||||
Mailbox format: extension[:extension1[:extension2]][@context]
|
||||
*/
|
||||
char* mailboxNumbers = strsep(&mailboxMember, "@");
|
||||
const char* mailboxContext = (mailboxMember != 0) ? mailboxMember : "default";
|
||||
const char* mailboxNumber = strsep (&mailboxNumbers, ":");
|
||||
const char* controllingUserNumber = strsep (&mailboxNumbers, ":");
|
||||
const char* controllingUserProvidedNumber = mailboxNumbers;
|
||||
if ((mailboxNumber != 0) && (*mailboxNumber != 0)) {
|
||||
cc_capi_mwi_mailbox_t* mwiSubscribtion = ast_malloc(sizeof(*mwiSubscribtion));
|
||||
if (mwiSubscribtion != 0) {
|
||||
mwiSubscribtion->mailboxNumber = pbx_capi_build_facility_number(conf->mwifacptynrtype, conf->mwifacptynrton, conf->mwifacptynrpres, mailboxNumber);
|
||||
mwiSubscribtion->mailboxContext = ast_strdup(mailboxContext);
|
||||
mwiSubscribtion->controllingUserNumber = pbx_capi_build_facility_number(conf->mwifacptynrtype, conf->mwifacptynrton, conf->mwifacptynrpres, controllingUserNumber);
|
||||
mwiSubscribtion->controllingUserProvidedNumber = pbx_capi_build_facility_number(conf->mwifacptynrtype, conf->mwifacptynrton, conf->mwifacptynrpres, controllingUserProvidedNumber);
|
||||
mwiSubscribtion->controller = mwiController;
|
||||
mwiSubscribtion->mwiSubscribtion = 0;
|
||||
mwiSubscribtion->basicService = conf->mwibasicservice;
|
||||
mwiSubscribtion->invocationMode = conf->mwiinvocation;
|
||||
|
||||
if ((mwiSubscribtion->mailboxNumber == 0) || (mwiSubscribtion->mailboxContext == 0) ||
|
||||
((mwiSubscribtion->controllingUserNumber == 0) && (controllingUserNumber != 0)) ||
|
||||
((mwiSubscribtion->controllingUserProvidedNumber == 0) && (controllingUserProvidedNumber != 0))) {
|
||||
ast_free(mwiSubscribtion->mailboxNumber);
|
||||
ast_free(mwiSubscribtion->mailboxContext);
|
||||
ast_free(mwiSubscribtion->controllingUserNumber);
|
||||
ast_free(mwiSubscribtion->controllingUserProvidedNumber);
|
||||
ast_free(mwiSubscribtion);
|
||||
} else {
|
||||
cc_verbose (4, 0, "CAPI%d add MWI subscribtion for '%s@%s' user '%s' control '%s'\n",
|
||||
mwiSubscribtion->controller->controller,
|
||||
mwiSubscribtion->mailboxNumber + 4,
|
||||
mwiSubscribtion->mailboxContext,
|
||||
(mwiSubscribtion->controllingUserNumber != 0) ? (char*)mwiSubscribtion->controllingUserNumber+4 : "",
|
||||
(mwiSubscribtion->controllingUserProvidedNumber != 0) ? (char*)mwiSubscribtion->controllingUserProvidedNumber+4 : "");
|
||||
|
||||
memset(&mwiSubscribtion->link, 0x00, sizeof(mwiSubscribtion->link));
|
||||
AST_LIST_INSERT_TAIL(&mwiController->mwiSubscribtions, mwiSubscribtion, link);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __CHAN_CAPI_MWI_H__
|
||||
#define __CHAN_CAPI_MWI_H__
|
||||
|
||||
extern int pbx_capi_mwi(struct ast_channel *c, char *info);
|
||||
extern int pbx_capi_xmit_mwi(
|
||||
const struct cc_capi_controller *controller,
|
||||
unsigned short basicService,
|
||||
unsigned int numberOfMessages,
|
||||
unsigned short messageStatus,
|
||||
unsigned short messageReference,
|
||||
unsigned short invocationMode,
|
||||
const unsigned char* receivingUserNumber,
|
||||
const unsigned char* controllingUserNumber,
|
||||
const unsigned char* controllingUserProvidedNumber,
|
||||
const unsigned char* timeX208);
|
||||
extern int pbx_capi_xmit_mwi_deactivate(
|
||||
const struct cc_capi_controller *controller,
|
||||
unsigned short basicService,
|
||||
unsigned short invocationMode,
|
||||
const unsigned char* receivingUserNumber,
|
||||
const unsigned char* controllingUserNumber);
|
||||
extern void pbx_capi_register_mwi(struct cc_capi_controller *controller);
|
||||
extern void pbx_capi_refresh_mwi(struct cc_capi_controller *controller);
|
||||
extern void pbx_capi_unregister_mwi(struct cc_capi_controller *controller);
|
||||
extern void pbx_capi_cleanup_mwi(struct cc_capi_controller *controller);
|
||||
extern unsigned char* pbx_capi_build_facility_number(
|
||||
unsigned char mwifacptynrtype,
|
||||
unsigned char mwifacptynrton,
|
||||
unsigned char mwifacptynrpres,
|
||||
const char* number);
|
||||
|
||||
void pbx_capi_init_mwi_server (
|
||||
struct cc_capi_controller *mwiController,
|
||||
const struct cc_capi_conf *conf);
|
||||
|
||||
#endif
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __CHAN_CAPI_PLATFORM_H__
|
||||
#define __CHAN_CAPI_PLATFORM_H__
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ struct rose_component {
|
|||
} while (0)
|
||||
|
||||
|
||||
#define free_null(x) { free(x); x = NULL; }
|
||||
#define free_null(x) { ast_free(x); x = NULL; }
|
||||
|
||||
/* Common QSIG structs */
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ unsigned int cc_qsig_asn197ade_get_pns(unsigned char *data, int *idx, struct asn
|
|||
|
||||
myidx += res;
|
||||
if (strlen(buf)) {
|
||||
ns->partyNumber = strdup(buf);
|
||||
ns->partyNumber = ast_strdup(buf);
|
||||
}
|
||||
|
||||
/* get screening indicator */
|
||||
|
@ -170,7 +170,7 @@ unsigned int cc_qsig_asn197ade_get_pns(unsigned char *data, int *idx, struct asn
|
|||
|
||||
myidx += res;
|
||||
if (strlen(buf)) {
|
||||
ns->partyNumber = strdup(buf);
|
||||
ns->partyNumber = ast_strdup(buf);
|
||||
}
|
||||
|
||||
/* get screening indicator */
|
||||
|
|
|
@ -222,7 +222,7 @@ unsigned char *cc_qsig_asn1_oid2str(unsigned char *data, int size)
|
|||
*s++ = 0;
|
||||
|
||||
s = buf;
|
||||
return (unsigned char *) strdup((char*)s);
|
||||
return (unsigned char *) ast_strdup((char*)s);
|
||||
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,7 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
|
|||
oidstr = cc_qsig_asn1_oid2str(invoke->oid_bin, invoke->oid_len);
|
||||
if (oidstr) {
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
|
||||
free(oidstr);
|
||||
ast_free(oidstr);
|
||||
} else {
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protoco
|
|||
oidstr = cc_qsig_asn1_oid2str(invoke->oid_bin, invoke->oid_len);
|
||||
if (oidstr) {
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (%s)\n", oidstr);
|
||||
free(oidstr);
|
||||
ast_free(oidstr);
|
||||
} else {
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: INVOKE OP (unknown - OID not displayable)\n");
|
||||
}
|
||||
|
@ -698,16 +698,16 @@ static void pbx_capi_qsig_handle_ctc(struct cc_qsig_invokedata *invoke, struct c
|
|||
switch (ii->state) {
|
||||
case CAPI_STATE_ALERTING:
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: peer is in state ALERTING, PATH REPLACE follows after CONNECT...\n");
|
||||
ii->qsig_data.pr_propose_cid = strdup("123"); /* HACK: need an dynamic ID */
|
||||
ii->qsig_data.pr_propose_pn = strdup(i->qsig_data.if_pr_propose_pn);
|
||||
ii->qsig_data.pr_propose_cid = ast_strdup("123"); /* HACK: need an dynamic ID */
|
||||
ii->qsig_data.pr_propose_pn = ast_strdup(i->qsig_data.if_pr_propose_pn);
|
||||
ii->qsig_data.pr_propose_doinboundbridge = 1;
|
||||
i->qsig_data.pr_propose_doinboundbridge = 1;
|
||||
i->qsig_data.partner_plci = ii->PLCI;
|
||||
break;
|
||||
case CAPI_STATE_CONNECTED:
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_3 "QSIG: peer is CONNECTED...\n");
|
||||
i->qsig_data.pr_propose_cid = strdup("123"); /* HACK: need an dynamic ID */
|
||||
i->qsig_data.pr_propose_pn = strdup(i->qsig_data.if_pr_propose_pn);
|
||||
i->qsig_data.pr_propose_cid = ast_strdup("123"); /* HACK: need an dynamic ID */
|
||||
i->qsig_data.pr_propose_pn = ast_strdup(i->qsig_data.if_pr_propose_pn);
|
||||
ii->qsig_data.pr_propose_doinboundbridge = 1;
|
||||
ii->qsig_data.partner_plci = i->PLCI;
|
||||
|
||||
|
@ -1003,7 +1003,7 @@ unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i
|
|||
}
|
||||
|
||||
cc_qsig_build_facility_struct(data, &dataidx, protocolvar, APDUINTERPRETATION_IGNORE, &nfe);
|
||||
cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 0, i->owner->cid.cid_name);
|
||||
cc_qsig_encode_ecma_name_invoke(data, &dataidx, &invoke, i, 0, pbx_capi_get_connectedname (i->owner, ""));
|
||||
cc_qsig_add_invoke(data, &dataidx, &invoke, i);
|
||||
|
||||
if (add_externalinfo) {
|
||||
|
@ -1203,7 +1203,7 @@ int pbx_capi_qsig_ct(struct ast_channel *c, char *param)
|
|||
return -1;
|
||||
}
|
||||
|
||||
marker = strsep(¶m, "|");
|
||||
marker = strsep(¶m, COMMANDSEPARATOR);
|
||||
|
||||
callmark = atoi(marker);
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * QSIG_CT: using call marker %i(%s)\n", callmark, marker);
|
||||
|
@ -1330,6 +1330,7 @@ void cc_pbx_qsig_conf_interface_value(struct cc_capi_conf *conf, struct ast_vari
|
|||
}
|
||||
|
||||
CONF_INTEGER(conf->qsigfeat, "qsig")
|
||||
CONF_TRUE(conf->divaqsig, "divaqsig", 1)
|
||||
CONF_STRING(conf->qsigconf.if_pr_propose_pn, "qsig_prnum")
|
||||
|
||||
|
||||
|
@ -1351,15 +1352,15 @@ static void qsig_cleanup_channel(struct capi_pvt *i)
|
|||
i->qsig_data.pr_propose_sentback = 0;
|
||||
i->qsig_data.pr_propose_doinboundbridge = 0;
|
||||
if (i->qsig_data.pr_propose_cid) {
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
ast_free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
}
|
||||
if (i->qsig_data.pr_propose_pn) {
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
ast_free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
}
|
||||
if (i->qsig_data.dnameid) {
|
||||
free(i->qsig_data.dnameid);
|
||||
ast_free(i->qsig_data.dnameid);
|
||||
i->qsig_data.dnameid = NULL;
|
||||
}
|
||||
|
||||
|
@ -1528,8 +1529,8 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
|
|||
ii->qsig_data.pr_propose_sentback = 1;
|
||||
} else { /* Path Replacement has to be sent back after Connect on second line */
|
||||
ii->qsig_data.pr_propose_sendback = 1;
|
||||
ii->qsig_data.pr_propose_cid = strdup(i->qsig_data.pr_propose_cid);
|
||||
ii->qsig_data.pr_propose_pn = strdup(i->qsig_data.pr_propose_pn);
|
||||
ii->qsig_data.pr_propose_cid = ast_strdup(i->qsig_data.pr_propose_cid);
|
||||
ii->qsig_data.pr_propose_pn = ast_strdup(i->qsig_data.pr_propose_pn);
|
||||
ii->qsig_data.pr_propose_active = 1;
|
||||
}
|
||||
} else
|
||||
|
@ -1537,9 +1538,9 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
|
|||
|
||||
|
||||
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
ast_free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
ast_free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
}
|
||||
|
||||
|
@ -1553,9 +1554,9 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
|
|||
ast_channel_masquerade(ii->owner, chanx);
|
||||
}
|
||||
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
ast_free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
ast_free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
}
|
||||
|
||||
|
@ -1612,9 +1613,9 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
|
|||
);
|
||||
|
||||
i->qsig_data.pr_propose_sendback = 0;
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
ast_free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
ast_free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
|
||||
i->qsig_data.pr_propose_sentback = 1;
|
||||
|
@ -1640,9 +1641,9 @@ void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsign
|
|||
"()(()()()s)", fac );
|
||||
|
||||
i->qsig_data.pr_propose_sendback = 0;
|
||||
free(i->qsig_data.pr_propose_cid);
|
||||
ast_free(i->qsig_data.pr_propose_cid);
|
||||
i->qsig_data.pr_propose_cid = NULL;
|
||||
free(i->qsig_data.pr_propose_pn);
|
||||
ast_free(i->qsig_data.pr_propose_pn);
|
||||
i->qsig_data.pr_propose_pn = NULL;
|
||||
|
||||
i->qsig_data.pr_propose_sentback = 1;
|
||||
|
|
|
@ -75,16 +75,20 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
|
|||
|
||||
switch (invoke->type) {
|
||||
case 0: /* Calling Name */
|
||||
i->owner->cid.cid_name = strdup(callername); /* Save name to callerid */
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
ast_set_callerid(i->owner, NULL, callername, NULL);
|
||||
#else
|
||||
i->owner->cid.cid_name = ast_strdup(callername); /* Save name to callerid */
|
||||
#endif
|
||||
break;
|
||||
case 1: /* Called Name */
|
||||
case 2: /* Connected Name */
|
||||
case 3: /* Busy Name */
|
||||
if (i->qsig_data.dnameid) { /* this facility may come more than once - if so, then update this value */
|
||||
cc_qsig_verbose( 1, VERBOSE_PREFIX_4 " * deleting previously received name.\n", nametype, namelength, callername);
|
||||
free(i->qsig_data.dnameid);
|
||||
ast_free(i->qsig_data.dnameid);
|
||||
}
|
||||
i->qsig_data.dnameid = strdup(callername); /* save name as destination in qsig specific fields */
|
||||
i->qsig_data.dnameid = ast_strdup(callername); /* save name as destination in qsig specific fields */
|
||||
/* there's no similarly field in asterisk */
|
||||
break;
|
||||
default:
|
||||
|
@ -112,7 +116,7 @@ void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct cap
|
|||
* returns
|
||||
* always 0
|
||||
*/
|
||||
int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype, char * name)
|
||||
int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype, const char * name)
|
||||
{
|
||||
unsigned char namebuf[51];
|
||||
unsigned char data[255];
|
||||
|
@ -382,40 +386,47 @@ void cc_qsig_encode_ecma_calltransfer(unsigned char * buf, unsigned int *idx, st
|
|||
|
||||
if (param) { /* got Call Transfer Parameters */
|
||||
if (info) {
|
||||
cid = strsep(¶m, "|");
|
||||
cid = strsep(¶m, COMMANDSEPARATOR);
|
||||
cidlen = strlen(cid);
|
||||
if (cidlen > 20) /* HACK: stop action here, maybe we have invalid data */
|
||||
cidlen = 20;
|
||||
} else {
|
||||
char *tmp = strsep(¶m, "|");
|
||||
char *tmp = strsep(¶m, COMMANDSEPARATOR);
|
||||
tmp = NULL;
|
||||
cid = strsep(¶m, "|");
|
||||
cid = strsep(¶m, COMMANDSEPARATOR);
|
||||
cidlen = strlen(cid);
|
||||
if (cidlen > 20) /* HACK: stop action here, maybe we have invalid data */
|
||||
cidlen = 20;
|
||||
|
||||
ccanswer = strsep(¶m, "|");
|
||||
ccanswer = strsep(¶m, COMMANDSEPARATOR);
|
||||
if (ccanswer[0])
|
||||
icanswer = ccanswer[0] - 0x30;
|
||||
}
|
||||
} else {
|
||||
/* cid = strdup(i->owner->cid.cid_num);*/ /* Here we get the Asterisk extension */
|
||||
/* cid = ast_strdup(i->owner->cid.cid_num);*/ /* Here we get the Asterisk extension */
|
||||
if (info) { /* info is >0 on outbound channel (second facility) */
|
||||
struct capi_pvt *ii = capi_find_interface_by_plci(i->qsig_data.partner_plci);
|
||||
|
||||
cid = strdup(i->cid);
|
||||
cid = ast_strdup(i->cid);
|
||||
cidlen = strlen(cid);
|
||||
|
||||
if (ii) {
|
||||
/* send callers name to user B */
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
if (ii->owner->caller.id.name.valid ) {
|
||||
name = ast_strdupa(S_COR(ii->owner->caller.id.name.valid, ii->owner->caller.id.name.str, ""));
|
||||
namelength = strlen(name);
|
||||
}
|
||||
#else
|
||||
if (ii->owner->cid.cid_name) {
|
||||
name = ast_strdupa(ii->owner->cid.cid_name);
|
||||
namelength = strlen(name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else { /* have to build first facility - send destination number back to inbound channel */
|
||||
struct capi_pvt *ii = capi_find_interface_by_plci(i->qsig_data.partner_plci);
|
||||
cid = strdup(ii->dnid);
|
||||
cid = ast_strdup(ii->dnid);
|
||||
cidlen = strlen(cid);
|
||||
|
||||
if (ii) {
|
||||
|
@ -479,7 +490,7 @@ void cc_qsig_encode_ecma_calltransfer(unsigned char * buf, unsigned int *idx, st
|
|||
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Sending QSIG_CT: %i->%s\n", info, cid);
|
||||
|
||||
if (cid)
|
||||
free(cid);
|
||||
ast_free(cid);
|
||||
|
||||
}
|
||||
|
||||
|
@ -552,7 +563,7 @@ unsigned int cc_qsig_decode_ecma_calltransfer(struct cc_qsig_invokedata *invoke,
|
|||
if (data[myidx] == ASN1_TC_APPLICATION) {
|
||||
myidx++;
|
||||
/* TODO: check size -> could be bigger than 256 bytes - MSB is set then */
|
||||
ctc->basicCallInfoElements = malloc(data[myidx]);
|
||||
ctc->basicCallInfoElements = ast_malloc(data[myidx]);
|
||||
if (ctc->basicCallInfoElements) {
|
||||
memcpy(ctc->basicCallInfoElements, &data[myidx+1], data[myidx] );
|
||||
} else {
|
||||
|
@ -566,7 +577,7 @@ unsigned int cc_qsig_decode_ecma_calltransfer(struct cc_qsig_invokedata *invoke,
|
|||
if (data[myidx] != ASN1_ENUMERATED) { /* Maybe we get an name (OPTIONAL) */
|
||||
myidx += cc_qsig_asn197no_get_name(ct_name, ASN197NO_NAME_STRSIZE+1, &namelength, &myidx, data );
|
||||
if (namelength)
|
||||
ctc->redirectionName = strdup(ct_name);
|
||||
ctc->redirectionName = ast_strdup(ct_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,12 +618,12 @@ void cc_qsig_encode_ecma_sscalltransfer(unsigned char * buf, unsigned int *idx,
|
|||
char c[255];
|
||||
int ix = 0;
|
||||
|
||||
cidsrc = strsep(¶m, "|");
|
||||
cidsrc = strsep(¶m, COMMANDSEPARATOR);
|
||||
srclen = strlen(cidsrc);
|
||||
if (srclen > 20) /* HACK: stop action here, maybe we have invalid data */
|
||||
srclen = 20;
|
||||
|
||||
ciddst = strsep(¶m, "|");
|
||||
ciddst = strsep(¶m, COMMANDSEPARATOR);
|
||||
dstlen = strlen(ciddst);
|
||||
if (dstlen > 20) /* HACK: stop action here, maybe we have invalid data */
|
||||
dstlen = 20;
|
||||
|
@ -718,8 +729,8 @@ void cc_qsig_op_ecma_isdn_prpropose(struct cc_qsig_invokedata *invoke, struct ca
|
|||
}
|
||||
|
||||
|
||||
i->qsig_data.pr_propose_cid = strdup(callid);
|
||||
i->qsig_data.pr_propose_pn = strdup(reroutingnr);
|
||||
i->qsig_data.pr_propose_cid = ast_strdup(callid);
|
||||
i->qsig_data.pr_propose_pn = ast_strdup(reroutingnr);
|
||||
|
||||
cc_qsig_verbose( 0, VERBOSE_PREFIX_4 " * Got QSIG_PATHREPLACEMENT_PROPOSE Call identity: %s, Party number: %s (%i)\n", callid, reroutingnr, temp);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ struct cc_qsig_ccbsreq {
|
|||
*/
|
||||
|
||||
extern void cc_qsig_op_ecma_isdn_namepres(struct cc_qsig_invokedata *invoke, struct capi_pvt *i);
|
||||
extern int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype, char *name);
|
||||
extern int cc_qsig_encode_ecma_name_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, int nametype, const char *name);
|
||||
|
||||
extern int cc_qsig_encode_ecma_isdn_leginfo3_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i, char *name);
|
||||
|
||||
|
|
|
@ -155,19 +155,32 @@ _cstruct capi_rtp_ncpi(struct capi_pvt *i)
|
|||
*/
|
||||
int capi_alloc_rtp(struct capi_pvt *i)
|
||||
{
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
struct ast_sockaddr addr;
|
||||
struct ast_sockaddr us;
|
||||
#else
|
||||
struct ast_hostent ahp;
|
||||
struct hostent *hp;
|
||||
struct in_addr addr;
|
||||
struct sockaddr_in us;
|
||||
#endif
|
||||
#ifndef CC_AST_HAS_VERSION_1_4
|
||||
char temp[MAXHOSTNAMELEN];
|
||||
#endif
|
||||
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
ast_sockaddr_parse(&addr, "localhost:0", 0);
|
||||
#else
|
||||
hp = ast_gethostbyname("localhost", &ahp);
|
||||
memcpy(&addr, hp->h_addr, sizeof(addr));
|
||||
#endif
|
||||
|
||||
#ifdef CC_AST_HAS_RTP_ENGINE_H
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
i->rtp = ast_rtp_instance_new(NULL, NULL, &addr, NULL);
|
||||
#else
|
||||
i->rtp = ast_rtp_instance_new(NULL, NULL, (struct sockaddr_in *)&addr, NULL);
|
||||
#endif
|
||||
#else
|
||||
i->rtp = ast_rtp_new_with_bindaddr(NULL, NULL, 0, 0, addr);
|
||||
#endif
|
||||
|
@ -185,12 +198,16 @@ int capi_alloc_rtp(struct capi_pvt *i)
|
|||
#endif
|
||||
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: alloc rtp socket on %s:%d\n",
|
||||
i->vname,
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
ast_sockaddr_stringify(&us), ntohs(ast_sockaddr_port(&us)));
|
||||
#else
|
||||
#ifdef CC_AST_HAS_VERSION_1_4
|
||||
ast_inet_ntoa(us.sin_addr),
|
||||
#else
|
||||
ast_inet_ntoa(temp, sizeof(temp), us.sin_addr),
|
||||
#endif
|
||||
ntohs(us.sin_port));
|
||||
#endif
|
||||
i->timestamp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -200,14 +217,16 @@ int capi_alloc_rtp(struct capi_pvt *i)
|
|||
*/
|
||||
int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
|
||||
{
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
struct ast_sockaddr us;
|
||||
#else
|
||||
struct sockaddr_in us;
|
||||
socklen_t uslen = sizeof(us);
|
||||
#endif
|
||||
int len;
|
||||
socklen_t uslen;
|
||||
unsigned int *rtpheader;
|
||||
unsigned char buf[256];
|
||||
|
||||
uslen = sizeof(us);
|
||||
|
||||
if (!(i->rtp)) {
|
||||
cc_log(LOG_ERROR, "rtp struct is NULL\n");
|
||||
return -1;
|
||||
|
@ -228,12 +247,16 @@ int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
|
|||
}
|
||||
|
||||
while(1) {
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
len = ast_recvfrom(ast_rtp_instance_fd(i->rtp, 0), buf, sizeof(buf), 0, &us);
|
||||
#else
|
||||
#ifdef CC_AST_HAS_RTP_ENGINE_H
|
||||
len = recvfrom(ast_rtp_instance_fd(i->rtp, 0),
|
||||
buf, sizeof(buf), 0, (struct sockaddr *)&us, &uslen);
|
||||
#else
|
||||
len = recvfrom(ast_rtp_fd(i->rtp),
|
||||
buf, sizeof(buf), 0, (struct sockaddr *)&us, &uslen);
|
||||
#endif
|
||||
#endif
|
||||
if (len <= 0)
|
||||
break;
|
||||
|
@ -281,7 +304,11 @@ int capi_write_rtp(struct capi_pvt *i, struct ast_frame *f)
|
|||
struct ast_frame *capi_read_rtp(struct capi_pvt *i, unsigned char *buf, int len)
|
||||
{
|
||||
struct ast_frame *f;
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
struct ast_sockaddr us;
|
||||
#else
|
||||
struct sockaddr_in us;
|
||||
#endif
|
||||
|
||||
if (!(i->owner))
|
||||
return NULL;
|
||||
|
@ -299,10 +326,14 @@ struct ast_frame *capi_read_rtp(struct capi_pvt *i, unsigned char *buf, int len)
|
|||
ast_rtp_set_peer(i->rtp, &us);
|
||||
#endif
|
||||
|
||||
#ifdef CC_AST_HAS_AST_SOCKADDR
|
||||
if (len != ast_sendto(ast_rtp_instance_fd(i->rtp, 0), buf, len, 0, &us))
|
||||
#else
|
||||
#ifdef CC_AST_HAS_RTP_ENGINE_H
|
||||
if (len != sendto(ast_rtp_instance_fd(i->rtp, 0), buf, len, 0, (struct sockaddr *)&us, sizeof(us)))
|
||||
#else
|
||||
if (len != sendto(ast_rtp_fd(i->rtp), buf, len, 0, (struct sockaddr *)&us, sizeof(us)))
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: RTP sendto error\n",
|
||||
|
@ -425,12 +456,43 @@ void voice_over_ip_profile(struct cc_capi_controller *cp)
|
|||
}
|
||||
if (payload1 & 0x00040000) {
|
||||
cp->rtpcodec |= AST_FORMAT_G729A;
|
||||
cc_verbose(3, 0, "G.729");
|
||||
cc_verbose(3, 0, "G.729 ");
|
||||
}
|
||||
if (payload1 & (1U << 27)) {
|
||||
cp->rtpcodec |= AST_FORMAT_ILBC;
|
||||
cc_verbose(3, 0, "iLBC");
|
||||
cc_verbose(3, 0, "iLBC ");
|
||||
}
|
||||
#ifdef AST_FORMAT_G722
|
||||
if (payload1 & (1U << 9)) {
|
||||
cp->rtpcodec |= AST_FORMAT_G722;
|
||||
cc_verbose(3, 0, "G.722 ");
|
||||
}
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SIREN7) && defined(AST_FORMAT_SIREN14)
|
||||
if (payload1 & (1U << 24)) {
|
||||
#ifdef AST_FORMAT_SIREN7
|
||||
cp->rtpcodec |= AST_FORMAT_SIREN7;
|
||||
cc_verbose(3, 0, "siren7 ");
|
||||
#endif
|
||||
#ifdef AST_FORMAT_SIREN14
|
||||
cp->rtpcodec |= AST_FORMAT_SIREN14;
|
||||
cc_verbose(3, 0, "siren14 ");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR) || defined(AST_FORMAT_SLINEAR16)
|
||||
if (payload1 & (1U << 1)) {
|
||||
#if defined(AST_FORMAT_SLINEAR)
|
||||
cp->rtpcodec |= AST_FORMAT_SLINEAR;
|
||||
cc_verbose(3, 0, "slin ");
|
||||
#endif
|
||||
#if defined(AST_FORMAT_SLINEAR16)
|
||||
cp->rtpcodec |= AST_FORMAT_SLINEAR16;
|
||||
cc_verbose(3, 0, "slin16 ");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
cc_verbose(3, 0, "\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include "chan_capi.h"
|
||||
#include "chan_capi_supplementary.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
#include <asterisk/event.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define CCBSNR_TYPE_CCBS 1
|
||||
|
@ -65,7 +68,7 @@ static void del_old_ccbsnr(void)
|
|||
} else {
|
||||
tmp->next = ccbsnr->next;
|
||||
}
|
||||
free(ccbsnr);
|
||||
ast_free(ccbsnr);
|
||||
break;
|
||||
}
|
||||
tmp = ccbsnr;
|
||||
|
@ -86,7 +89,7 @@ void cleanup_ccbsnr(void)
|
|||
while (ccbsnr) {
|
||||
tmp = ccbsnr;
|
||||
ccbsnr = ccbsnr->next;
|
||||
free(tmp);
|
||||
ast_free(tmp);
|
||||
}
|
||||
cc_mutex_unlock(&ccbsnr_lock);
|
||||
}
|
||||
|
@ -122,7 +125,7 @@ static void new_ccbsnr_id(char type, unsigned int plci,
|
|||
char buffer[CAPI_MAX_STRING];
|
||||
struct ccbsnr_s *ccbsnr;
|
||||
|
||||
ccbsnr = malloc(sizeof(struct ccbsnr_s));
|
||||
ccbsnr = ast_malloc(sizeof(struct ccbsnr_s));
|
||||
if (ccbsnr == NULL) {
|
||||
cc_log(LOG_ERROR, "Unable to allocate CCBS/CCNR struct.\n");
|
||||
return;
|
||||
|
@ -259,7 +262,7 @@ static void del_ccbsnr_ref(unsigned int plci, _cword ref)
|
|||
} else {
|
||||
tmp->next = ccbsnr->next;
|
||||
}
|
||||
free(ccbsnr);
|
||||
ast_free(ccbsnr);
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 CC_MESSAGE_NAME
|
||||
": PLCI=%#x CCBS/CCNR removed ref=0x%04x\n", plci, ref);
|
||||
break;
|
||||
|
@ -319,7 +322,7 @@ static void del_ccbsnr_id(unsigned int plci, _cword id)
|
|||
} else {
|
||||
tmp->next = ccbsnr->next;
|
||||
}
|
||||
free(ccbsnr);
|
||||
ast_free(ccbsnr);
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 CC_MESSAGE_NAME ": PLCI=%#x CCBS/CCNR removed "
|
||||
"id=0x%04x state=%d\n", plci, id, oldstate);
|
||||
} else {
|
||||
|
@ -399,14 +402,24 @@ static void ccbsnr_remote_user_free(_cmsg *CMSG, char type, unsigned int PLCI, _
|
|||
|
||||
c->priority = ccbsnr->priority;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
/*! \todo verify if necessary/complete */
|
||||
c->connected.id.number.valid = 1;
|
||||
ast_free (c->connected.id.number.str);
|
||||
c->connected.id.number.str = ast_strdup(handlename);
|
||||
|
||||
ast_free (c->dialed.number.str);
|
||||
c->dialed.number.str = ast_strdup (ccbsnr->exten);
|
||||
#else
|
||||
if (c->cid.cid_num) {
|
||||
free(c->cid.cid_num);
|
||||
ast_free(c->cid.cid_num);
|
||||
}
|
||||
c->cid.cid_num = strdup(handlename);
|
||||
c->cid.cid_num = ast_strdup(handlename);
|
||||
if (c->cid.cid_dnid) {
|
||||
free(c->cid.cid_dnid);
|
||||
ast_free(c->cid.cid_dnid);
|
||||
}
|
||||
c->cid.cid_dnid = strdup(ccbsnr->exten);
|
||||
c->cid.cid_dnid = ast_strdup(ccbsnr->exten);
|
||||
#endif
|
||||
|
||||
#ifndef CC_AST_HAS_EXT2_CHAN_ALLOC
|
||||
cc_copy_string(c->context, ccbsnr->context, sizeof(c->context));
|
||||
|
@ -561,6 +574,87 @@ int handle_facility_indication_supplementary(
|
|||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "contr%d: PLCI=%#x CCBS B-free ref=0x%04x\n",
|
||||
PLCI & 0xff, PLCI, infoword);
|
||||
break;
|
||||
case 0x8014: {/* MWI indication, stateless */
|
||||
const unsigned char* info = &FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4];
|
||||
unsigned short basicService = read_capi_word(info); info += 2;
|
||||
unsigned int numberOfMessages = read_capi_dword(info); info += 4;
|
||||
unsigned short messageStatus = read_capi_word(info); info += 2;
|
||||
unsigned short messageReference = read_capi_word(info); info += 2;
|
||||
char controllingUserNumberName[AST_MAX_EXTENSION];
|
||||
char controllingUserProvidedNumberName[AST_MAX_EXTENSION];
|
||||
char mwiTimeName[AST_MAX_EXTENSION];
|
||||
char mailboxName[AST_MAX_EXTENSION];
|
||||
|
||||
if (info[0] > 3) {
|
||||
memcpy(controllingUserNumberName,
|
||||
&info[4],
|
||||
MIN(AST_MAX_EXTENSION-1, info[0] - 3));
|
||||
controllingUserNumberName[MIN(AST_MAX_EXTENSION-1, info[0] - 3)] = 0;
|
||||
} else {
|
||||
controllingUserNumberName[0] = 0;
|
||||
}
|
||||
info += info[0] + 1;
|
||||
|
||||
if (info[0] > 3) {
|
||||
memcpy(controllingUserProvidedNumberName,
|
||||
&info[4],
|
||||
MIN(AST_MAX_EXTENSION-1, info[0] - 3));
|
||||
controllingUserProvidedNumberName[MIN(AST_MAX_EXTENSION-1, info[0] - 3)] = 0;
|
||||
} else {
|
||||
controllingUserProvidedNumberName[0] = 0;
|
||||
}
|
||||
info += info[0] + 1;
|
||||
|
||||
if (info[0] != 0) {
|
||||
memcpy(mwiTimeName, &info[1], MIN(AST_MAX_EXTENSION-1, info[0]));
|
||||
mwiTimeName[MIN(AST_MAX_EXTENSION-1, info[0])] = 0;
|
||||
} else {
|
||||
mwiTimeName[0] = 0;
|
||||
}
|
||||
info += info[0] + 1;
|
||||
|
||||
if (info[0] > 1) {
|
||||
memcpy(mailboxName, &info[2], MIN(AST_MAX_EXTENSION-1, info[0]));
|
||||
mailboxName[MIN(AST_MAX_EXTENSION-1, info[0]-1)] = 0;
|
||||
} else {
|
||||
mailboxName[0] = 0;
|
||||
}
|
||||
|
||||
if (messageStatus == 0 || messageStatus == 1) {
|
||||
cc_verbose(4, 0, VERBOSE_PREFIX_4 "CAPI%u Rx MWI %s for '%s@CAPI_Remote %s %s time '%s' %d messages ref %d service %d\n",
|
||||
PLCI & 0xff,
|
||||
messageStatus == 0 ? "add" : "del", mailboxName, controllingUserNumberName, controllingUserProvidedNumberName,
|
||||
mwiTimeName, numberOfMessages, messageReference, basicService);
|
||||
if (messageStatus == 0 && mailboxName[0] != 0) {
|
||||
#if defined(CC_AST_HAS_EVENT_MWI)
|
||||
struct ast_event *event;
|
||||
|
||||
if ((event = ast_event_new(AST_EVENT_MWI,
|
||||
AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailboxName,
|
||||
AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, "CAPI_Remote",
|
||||
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, MAX(1,numberOfMessages),
|
||||
AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, 0,
|
||||
AST_EVENT_IE_END))) {
|
||||
ast_event_queue_and_cache(event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
cc_verbose(4, 0, VERBOSE_PREFIX_1 "CAPI%u Rx MWI %s for '%s@default %s %s time '%s' service %d\n",
|
||||
messageStatus == 0 ? "add" : "del", mailboxName, controllingUserNumberName, controllingUserProvidedNumberName,
|
||||
mwiTimeName, basicService);
|
||||
}
|
||||
} return ret;
|
||||
case 0x8000: /* Hold notification */
|
||||
if ((i->isdnstate & CAPI_ISDN_STATE_EC) != 0) {
|
||||
cc_verbose(4, 0, VERBOSE_PREFIX_1 "%s: EC reset\n", i->vname);
|
||||
capi_echo_canceller(i, EC_FUNCTION_DISABLE);
|
||||
capi_echo_canceller(i, EC_FUNCTION_ENABLE);
|
||||
}
|
||||
return ret;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
|
@ -618,6 +712,11 @@ int handle_facility_indication_supplementary(
|
|||
i->vname, PLCI, infoword);
|
||||
show_capi_info(i, infoword);
|
||||
break;
|
||||
case 0x000d: /* CD */
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x CD Service Reason=0x%04x\n",
|
||||
i->vname, PLCI, infoword);
|
||||
show_capi_info(i, infoword);
|
||||
break;
|
||||
case 0x8013: /* CCBS info retain */
|
||||
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x CCBS unique id=0x%04x\n",
|
||||
i->vname, PLCI, infoword);
|
||||
|
@ -649,7 +748,7 @@ int handle_facility_indication_supplementary(
|
|||
* CAPI FACILITY_CONF supplementary
|
||||
*/
|
||||
void handle_facility_confirmation_supplementary(
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **i)
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **i, struct ast_channel** interface_owner)
|
||||
{
|
||||
_cword function;
|
||||
_cword serviceinfo;
|
||||
|
@ -694,7 +793,7 @@ void handle_facility_confirmation_supplementary(
|
|||
case 0x0012: /* CCBS call */
|
||||
cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: CCBS call confirmation (0x%04x) (PLCI=%#x)\n",
|
||||
name, serviceinfo, PLCI);
|
||||
capidev_handle_connection_conf(i, PLCI, FACILITY_CONF_INFO(CMSG), HEADER_MSGNUM(CMSG));
|
||||
capidev_handle_connection_conf(i, PLCI, FACILITY_CONF_INFO(CMSG), HEADER_MSGNUM(CMSG), interface_owner);
|
||||
break;
|
||||
default:
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: unhandled FACILITY_CONF supplementary function %04x\n",
|
||||
|
@ -712,7 +811,7 @@ int pbx_capi_ccpartybusy(struct ast_channel *c, char *data)
|
|||
struct ccbsnr_s *ccbsnr;
|
||||
char partybusy = 0;
|
||||
|
||||
slinkageid = strsep(&data, "|");
|
||||
slinkageid = strsep(&data, COMMANDSEPARATOR);
|
||||
yesno = data;
|
||||
|
||||
if (slinkageid) {
|
||||
|
@ -806,9 +905,9 @@ int pbx_capi_ccbs(struct ast_channel *c, char *data)
|
|||
MESSAGE_EXCHANGE_ERROR error;
|
||||
unsigned int ccbsnrstate;
|
||||
|
||||
slinkageid = strsep(&data, "|");
|
||||
context = strsep(&data, "|");
|
||||
exten = strsep(&data, "|");
|
||||
slinkageid = strsep(&data, COMMANDSEPARATOR);
|
||||
context = strsep(&data, COMMANDSEPARATOR);
|
||||
exten = strsep(&data, COMMANDSEPARATOR);
|
||||
priority = data;
|
||||
|
||||
if (slinkageid) {
|
||||
|
|
|
@ -19,7 +19,8 @@ extern void ListenOnSupplementary(unsigned controller);
|
|||
extern int handle_facility_indication_supplementary(
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i);
|
||||
extern void handle_facility_confirmation_supplementary(
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **i);
|
||||
_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **i,
|
||||
struct ast_channel** interface_owner);
|
||||
extern int pbx_capi_ccbs(struct ast_channel *c, char *data);
|
||||
extern int pbx_capi_ccbsstop(struct ast_channel *c, char *data);
|
||||
extern int pbx_capi_ccpartybusy(struct ast_channel *c, char *data);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "xlaw.h"
|
||||
|
@ -26,6 +27,22 @@
|
|||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_supplementary.h"
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
#include "platform.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
#include "diva_streaming_vector.h"
|
||||
#include "diva_streaming_manager.h"
|
||||
#include "chan_capi_divastreaming_utils.h"
|
||||
#endif
|
||||
#ifdef DIVA_STATUS
|
||||
#include "divastatus_ifc.h"
|
||||
#define CC_HW_STATE_OK(__x__) ((pbx_capi_get_controller((__x__)) == NULL) || \
|
||||
(pbx_capi_get_controller((__x__))->hwState != (int)DivaStatusHardwareStateERROR))
|
||||
#else
|
||||
#define CC_HW_STATE_OK(__x__) (1)
|
||||
#endif
|
||||
|
||||
int capidebug = 0;
|
||||
char *emptyid = "\0";
|
||||
|
||||
|
@ -123,7 +140,7 @@ void capi_remove_nullif(struct capi_pvt *i)
|
|||
cc_mutex_destroy(&i->lock);
|
||||
ast_cond_destroy(&i->event_trigger);
|
||||
controller_nullplcis[i->controller - 1]--;
|
||||
free(i);
|
||||
ast_free(i);
|
||||
break;
|
||||
}
|
||||
tmp = ii;
|
||||
|
@ -158,7 +175,7 @@ struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long control
|
|||
controllermask);
|
||||
/* find the next controller of mask with least plcis used */
|
||||
for (contrcount = 0; contrcount < maxcontr; contrcount++) {
|
||||
if ((controllermask & (1ULL << contrcount)) != 0) {
|
||||
if (((controllermask & (1ULL << contrcount)) != 0) && CC_HW_STATE_OK(contrcount + 1)) {
|
||||
if (controller_nullplcis[contrcount] < channelcount) {
|
||||
channelcount = controller_nullplcis[contrcount];
|
||||
controller = contrcount + 1;
|
||||
|
@ -166,7 +183,7 @@ struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long control
|
|||
}
|
||||
}
|
||||
|
||||
tmp = malloc(sizeof(struct capi_pvt));
|
||||
tmp = ast_malloc(sizeof(struct capi_pvt));
|
||||
if (!tmp) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -175,13 +192,15 @@ struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long control
|
|||
cc_mutex_init(&tmp->lock);
|
||||
ast_cond_init(&tmp->event_trigger, NULL);
|
||||
|
||||
snprintf(tmp->name, sizeof(tmp->name) - 1, "%s-NULLPLCI", c->name);
|
||||
snprintf(tmp->name, sizeof(tmp->name) - 1, "%s-NULLPLCI", (c != 0) ? c->name : "BRIDGE");
|
||||
snprintf(tmp->vname, sizeof(tmp->vname) - 1, "%s", tmp->name);
|
||||
|
||||
tmp->channeltype = CAPI_CHANNELTYPE_NULL;
|
||||
|
||||
tmp->used = c;
|
||||
tmp->peer = c;
|
||||
if (c == NULL)
|
||||
tmp->virtualBridgePeer = 1;
|
||||
|
||||
tmp->cip = CAPI_CIPI_SPEECH;
|
||||
tmp->transfercapability = PRI_TRANS_CAP_SPEECH;
|
||||
|
@ -198,9 +217,11 @@ struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long control
|
|||
tmp->txgain = 1.0;
|
||||
capi_gains(&tmp->g, 1.0, 1.0);
|
||||
|
||||
if (!(capi_create_reader_writer_pipe(tmp))) {
|
||||
free(tmp);
|
||||
return NULL;
|
||||
if (c != 0) {
|
||||
if (!(capi_create_reader_writer_pipe(tmp))) {
|
||||
ast_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
tmp->bproto = CC_BPROTO_TRANSPARENT;
|
||||
|
@ -219,19 +240,45 @@ struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long control
|
|||
tmp->state = CAPI_STATE_CONNECTPENDING;
|
||||
tmp->MessageNumber = get_capi_MessageNumber();
|
||||
|
||||
capi_sendf(NULL, 0, CAPI_CONNECT_REQ, controller, tmp->MessageNumber,
|
||||
#ifdef DIVA_STREAMING
|
||||
tmp->diva_stream_entry = 0;
|
||||
if (pbx_capi_streaming_supported (tmp) != 0) {
|
||||
capi_DivaStreamingOn(tmp, 1, tmp->MessageNumber);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (c == NULL) {
|
||||
cc_mutex_lock(&tmp->lock);
|
||||
}
|
||||
capi_sendf((c != NULL) ? NULL : tmp, c == NULL, CAPI_CONNECT_REQ, controller, tmp->MessageNumber,
|
||||
"w()()()()(www()()()())()()()((wwbbb)()()())",
|
||||
0, 1,1,0, 3,0,0,0,0);
|
||||
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: created null-interface on controller %d.\n",
|
||||
tmp->vname, tmp->controller);
|
||||
if (c == NULL) {
|
||||
cc_mutex_unlock(&tmp->lock);
|
||||
if (tmp->PLCI == 0) {
|
||||
cc_log(LOG_WARNING, "%s: failed to create\n", tmp->vname);
|
||||
capi_remove_nullif(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
}
|
||||
if (tmp != NULL) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: created null-interface on controller %d.\n",
|
||||
tmp->vname, tmp->controller);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long controllermask, struct capi_pvt *data_plci_ifc) {
|
||||
struct capi_pvt *capi_mkresourceif(
|
||||
struct ast_channel *c,
|
||||
unsigned long long controllermask,
|
||||
struct capi_pvt *data_plci_ifc,
|
||||
cc_format_t codecs,
|
||||
int all)
|
||||
{
|
||||
struct capi_pvt *data_ifc /*, *line_ifc */;
|
||||
unsigned int controller = 1;
|
||||
int fmt = 0;
|
||||
|
||||
if (data_plci_ifc == 0) {
|
||||
int contrcount;
|
||||
|
@ -244,7 +291,7 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
|
||||
/* find the next controller of mask with least plcis used */
|
||||
for (contrcount = 0; contrcount < maxcontr; contrcount++) {
|
||||
if ((controllermask & (1ULL << contrcount)) != 0) {
|
||||
if (((controllermask & (1ULL << contrcount)) != 0) && CC_HW_STATE_OK(contrcount + 1)) {
|
||||
if (controller_nullplcis[contrcount] < channelcount) {
|
||||
channelcount = controller_nullplcis[contrcount];
|
||||
controller = contrcount + 1;
|
||||
|
@ -253,9 +300,13 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
}
|
||||
} else {
|
||||
controller = data_plci_ifc->controller;
|
||||
codecs = (all != 0) ? pbx_capi_get_controller_codecs (controller) : codecs;
|
||||
fmt = pbx_capi_get_controller_codecs (controller) & codecs & c->nativeformats;
|
||||
if (fmt != 0)
|
||||
fmt = ast_best_codec(fmt);
|
||||
}
|
||||
|
||||
data_ifc = malloc(sizeof(struct capi_pvt));
|
||||
data_ifc = ast_malloc(sizeof(struct capi_pvt));
|
||||
if (data_ifc == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -282,7 +333,8 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
data_ifc->ecTail = EC_DEFAULT_TAIL;
|
||||
data_ifc->isdnmode = CAPI_ISDNMODE_MSN;
|
||||
data_ifc->ecSelector = FACILITYSELECTOR_ECHO_CANCEL;
|
||||
data_ifc->capability = capi_capability;
|
||||
data_ifc->capability = (fmt != 0 && data_plci_ifc != 0) ? fmt : capi_capability;
|
||||
data_ifc->codec = (fmt != 0 && data_plci_ifc != 0) ? fmt : data_ifc->codec;
|
||||
|
||||
data_ifc->rxgain = 1.0;
|
||||
data_ifc->txgain = 1.0;
|
||||
|
@ -290,7 +342,7 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
|
||||
if (data_plci_ifc == 0) {
|
||||
if (!(capi_create_reader_writer_pipe(data_ifc))) {
|
||||
free(data_ifc);
|
||||
ast_free(data_ifc);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -298,7 +350,7 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
data_ifc->writerfd = -1;
|
||||
}
|
||||
|
||||
data_ifc->bproto = CC_BPROTO_TRANSPARENT;
|
||||
data_ifc->bproto = (fmt != 0 && data_plci_ifc != 0) ? CC_BPROTO_VOCODER : CC_BPROTO_TRANSPARENT;
|
||||
data_ifc->doB3 = CAPI_B3_DONT;
|
||||
data_ifc->smoother = ast_smoother_new(CAPI_MAX_B3_BLOCK_SIZE);
|
||||
data_ifc->isdnstate |= CAPI_ISDN_STATE_PBX;
|
||||
|
@ -315,18 +367,31 @@ struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long con
|
|||
data_ifc->MessageNumber = get_capi_MessageNumber();
|
||||
|
||||
cc_mutex_lock(&data_ifc->lock);
|
||||
|
||||
#ifdef DIVA_STREAMING
|
||||
data_ifc->diva_stream_entry = 0;
|
||||
if (data_plci_ifc == 0) {
|
||||
capi_DivaStreamingStreamNotUsed(data_ifc, 1, data_ifc->MessageNumber);
|
||||
} else {
|
||||
if (pbx_capi_streaming_supported (data_ifc) != 0) {
|
||||
capi_DivaStreamingOn(data_ifc, 1, data_ifc->MessageNumber);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
capi_sendf(data_ifc,
|
||||
1,
|
||||
CAPI_MANUFACTURER_REQ,
|
||||
controller,
|
||||
data_ifc->MessageNumber,
|
||||
"dw(wbb(www()()()()))",
|
||||
"dw(wbb(wwws()()()))",
|
||||
_DI_MANU_ID,
|
||||
_DI_ASSIGN_PLCI,
|
||||
(data_plci_ifc == 0) ? 4 : 5, /* data */
|
||||
(data_plci_ifc == 0) ? 0 : (unsigned char)(data_plci_ifc->PLCI >> 8), /* bchannel */
|
||||
1, /* connect */
|
||||
1, 1, 0);
|
||||
(data_ifc->bproto == CC_BPROTO_VOCODER) ? 0x1f : 1, 1, 0,
|
||||
diva_get_b1_conf(data_ifc));
|
||||
cc_mutex_unlock(&data_ifc->lock);
|
||||
|
||||
if (data_plci_ifc != 0) {
|
||||
|
@ -529,7 +594,11 @@ MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG)
|
|||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 0;
|
||||
#ifdef DIVA_STREAMING
|
||||
tv.tv_usec = 5000;
|
||||
#else
|
||||
tv.tv_usec = 500000;
|
||||
#endif
|
||||
|
||||
Info = capi20_waitformessage(capi_ApplID, &tv);
|
||||
|
||||
|
@ -906,6 +975,8 @@ char *capi_info_string(unsigned int info)
|
|||
return "No call suspended";
|
||||
case 0x34D6:
|
||||
return "Call having the requested call identity has been cleared";
|
||||
case 0x34D7:
|
||||
return "User not a member of CUG";
|
||||
case 0x34D8:
|
||||
return "Incompatible destination";
|
||||
case 0x34DB:
|
||||
|
@ -1339,6 +1410,7 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
struct ast_frame *fsmooth;
|
||||
int txavg=0;
|
||||
int ret = 0;
|
||||
int B3Blocks = 1;
|
||||
|
||||
if (unlikely(!i)) {
|
||||
cc_log(LOG_ERROR, "channel has no interface\n");
|
||||
|
@ -1395,24 +1467,49 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
}
|
||||
return capi_write_rtp(i, f);
|
||||
}
|
||||
|
||||
if (unlikely(i->B3count >= CAPI_MAX_B3_BLOCKS)) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: B3count is full, dropping packet.\n",
|
||||
i->vname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (i->bproto == CC_BPROTO_VOCODER) {
|
||||
buf = &(i->send_buffer[(i->send_buffer_handle % CAPI_MAX_B3_BLOCKS) *
|
||||
(CAPI_MAX_B3_BLOCK_SIZE + AST_FRIENDLY_OFFSET)]);
|
||||
i->send_buffer_handle++;
|
||||
if (i->bproto == CC_BPROTO_VOCODER || (i->line_plci != 0 && i->line_plci->bproto == CC_BPROTO_VOCODER)) {
|
||||
#ifdef DIVA_STREAMING
|
||||
capi_DivaStreamLock();
|
||||
if (i->diva_stream_entry != 0) {
|
||||
int written = 0, ready = 0;
|
||||
|
||||
memcpy (buf, f->FRAME_DATA_PTR, f->datalen);
|
||||
B3Blocks = 0;
|
||||
if ((ready = (i->diva_stream_entry->diva_stream_state == DivaStreamActive)) &&
|
||||
(i->diva_stream_entry->diva_stream->get_tx_free (i->diva_stream_entry->diva_stream) > 2*CAPI_MAX_B3_BLOCK_SIZE+128)) {
|
||||
written = i->diva_stream_entry->diva_stream->write (i->diva_stream_entry->diva_stream, 8U << 8 | DIVA_STREAM_MESSAGE_TX_IDI_REQUEST, f->FRAME_DATA_PTR, f->datalen);
|
||||
i->diva_stream_entry->diva_stream->flush_stream(i->diva_stream_entry->diva_stream);
|
||||
}
|
||||
capi_DivaStreamUnLock ();
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", buf, f->datalen, i->send_buffer_handle, 0);
|
||||
error = written != f->datalen;
|
||||
if (unlikely(error != 0)) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: stream is %s, dropping packet.\n", i->vname, (ready != 0) ? "full" : "not ready");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef DIVA_STREAMING
|
||||
capi_DivaStreamUnLock ();
|
||||
#endif
|
||||
buf = &(i->send_buffer[(i->send_buffer_handle % CAPI_MAX_B3_BLOCKS) *
|
||||
(CAPI_MAX_B3_BLOCK_SIZE + AST_FRIENDLY_OFFSET)]);
|
||||
i->send_buffer_handle++;
|
||||
|
||||
memcpy (buf, f->FRAME_DATA_PTR, f->datalen);
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", buf, f->datalen, i->send_buffer_handle, 0);
|
||||
}
|
||||
if (likely(error == 0)) {
|
||||
cc_mutex_lock(&i->lock);
|
||||
i->B3count++;
|
||||
i->B3count += B3Blocks;
|
||||
i->B3q -= f->datalen;
|
||||
if (i->B3q < 0)
|
||||
i->B3q = 0;
|
||||
|
@ -1460,10 +1557,31 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
}
|
||||
}
|
||||
|
||||
error = 1;
|
||||
error = 1;
|
||||
if (i->B3q > 0) {
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", buf, fsmooth->datalen, i->send_buffer_handle, 0);
|
||||
#if defined(DIVA_STREAMING)
|
||||
if (i->diva_stream_entry != 0) {
|
||||
int written = 0, ready = 0;
|
||||
|
||||
B3Blocks = 0;
|
||||
capi_DivaStreamLock();
|
||||
if ((ready = (i->diva_stream_entry->diva_stream_state == DivaStreamActive)) &&
|
||||
(i->diva_stream_entry->diva_stream->get_tx_free (i->diva_stream_entry->diva_stream) > 2*CAPI_MAX_B3_BLOCK_SIZE+128)) {
|
||||
written = i->diva_stream_entry->diva_stream->write (i->diva_stream_entry->diva_stream, 8U << 8 | DIVA_STREAM_MESSAGE_TX_IDI_REQUEST, buf, fsmooth->datalen);
|
||||
i->diva_stream_entry->diva_stream->flush_stream(i->diva_stream_entry->diva_stream);
|
||||
}
|
||||
capi_DivaStreamUnLock ();
|
||||
|
||||
error = written != fsmooth->datalen;
|
||||
if (unlikely(error != 0)) {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: stream is %s, dropping packet.\n", i->vname, (ready != 0) ? "full" : "not ready");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", buf, fsmooth->datalen, i->send_buffer_handle, 0);
|
||||
}
|
||||
} else {
|
||||
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: too much voice to send for NCCI=%#x\n",
|
||||
i->vname, i->NCCI);
|
||||
|
@ -1471,7 +1589,7 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
|
||||
if (likely(!error)) {
|
||||
cc_mutex_lock(&i->lock);
|
||||
i->B3count++;
|
||||
i->B3count += B3Blocks;
|
||||
i->B3q -= fsmooth->datalen;
|
||||
if (i->B3q < 0)
|
||||
i->B3q = 0;
|
||||
|
@ -1481,3 +1599,97 @@ int capi_write_frame(struct capi_pvt *i, struct ast_frame *f)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
ast_channel_lock(chan) to be held while
|
||||
while accessing returned pointer
|
||||
*/
|
||||
const char* pbx_capi_get_cid(const struct ast_channel* c, const char* notAvailableVisual)
|
||||
{
|
||||
const char* cid;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
cid = S_COR(c->caller.id.number.valid, c->caller.id.number.str, notAvailableVisual);
|
||||
#else
|
||||
cid = c->cid.cid_num;
|
||||
#endif
|
||||
|
||||
return (cid);
|
||||
}
|
||||
|
||||
/*
|
||||
ast_channel_lock(chan) to be held while
|
||||
while accessing returned pointer
|
||||
*/
|
||||
const char* pbx_capi_get_callername(const struct ast_channel* c, const char* notAvailableVisual)
|
||||
{
|
||||
const char* name;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
name = S_COR(c->caller.id.name.valid, c->caller.id.name.str, notAvailableVisual);
|
||||
#else
|
||||
name = (c->cid.cid_name) ? c->cid.cid_name : notAvailableVisual;
|
||||
#endif
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
/*
|
||||
ast_channel_lock(chan) to be held while
|
||||
while accessing returned pointer
|
||||
*/
|
||||
const char* pbx_capi_get_connectedname(const struct ast_channel* c, const char* notAvailableVisual)
|
||||
{
|
||||
const char* name;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_8
|
||||
name = S_COR(c->connected.id.name.valid, c->connected.id.name.str, notAvailableVisual);
|
||||
#else
|
||||
name = (c->cid.cid_name) ? c->cid.cid_name : notAvailableVisual;
|
||||
#endif
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
const struct capi_pvt *pbx_capi_get_nulliflist(void)
|
||||
{
|
||||
return nulliflist;
|
||||
}
|
||||
|
||||
void pbx_capi_nulliflist_lock(void)
|
||||
{
|
||||
cc_mutex_lock(&nullif_lock);
|
||||
}
|
||||
|
||||
void pbx_capi_nulliflist_unlock(void)
|
||||
{
|
||||
cc_mutex_unlock(&nullif_lock);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get list of controllers. Stop parsing
|
||||
after non digit detected after separator
|
||||
character or end of string is reached
|
||||
*/
|
||||
char* pbx_capi_strsep_controller_list (char** param)
|
||||
{
|
||||
char *src, *p;
|
||||
|
||||
if ((param == NULL) || (*param == NULL) || (**param == 0))
|
||||
return NULL;
|
||||
|
||||
if (strchr(*param, '|') != NULL)
|
||||
return (strsep(param, "|"));
|
||||
|
||||
src = *param;
|
||||
p = src - 1;
|
||||
do {
|
||||
p = strchr(p+1, ',');
|
||||
} while ((p != NULL) && (isdigit(p[1]) != 0));
|
||||
|
||||
if (p != NULL)
|
||||
*p++ = 0;
|
||||
|
||||
*param = p;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
|
|
@ -54,11 +54,15 @@ extern int cc_add_peer_link_id(struct ast_channel *c);
|
|||
extern struct ast_channel *cc_get_peer_link_id(const char *p);
|
||||
extern void capi_remove_nullif(struct capi_pvt *i);
|
||||
extern struct capi_pvt *capi_mknullif(struct ast_channel *c, unsigned long long controllermask);
|
||||
struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long controllermask, struct capi_pvt *data_plci_ifc);
|
||||
struct capi_pvt *capi_mkresourceif(struct ast_channel *c, unsigned long long controllermask, struct capi_pvt *data_plci_ifc, cc_format_t codecs, int all);
|
||||
extern int capi_create_reader_writer_pipe(struct capi_pvt *i);
|
||||
extern struct ast_frame *capi_read_pipeframe(struct capi_pvt *i);
|
||||
extern int capi_write_frame(struct capi_pvt *i, struct ast_frame *f);
|
||||
extern int capi_verify_resource_plci(const struct capi_pvt *i);
|
||||
extern const char* pbx_capi_get_cid (const struct ast_channel* c, const char *notAvailableVisual);
|
||||
extern const char* pbx_capi_get_callername (const struct ast_channel* c, const char *notAvailableVisual);
|
||||
const char* pbx_capi_get_connectedname (const struct ast_channel* c, const char *notAvailableVisual);
|
||||
char* pbx_capi_strsep_controller_list (char** param);
|
||||
|
||||
#define capi_number(data, strip) \
|
||||
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
|
||||
|
@ -77,4 +81,17 @@ extern MESSAGE_EXCHANGE_ERROR capi_sendf(
|
|||
struct capi_pvt *capii, int waitconf,
|
||||
_cword command, _cdword Id, _cword Number, char * format, ...);
|
||||
|
||||
/*!
|
||||
\brief nulliflist
|
||||
*/
|
||||
const struct capi_pvt *pbx_capi_get_nulliflist(void);
|
||||
/*!
|
||||
\brief cc_mutex_lock(&nullif_lock)
|
||||
*/
|
||||
void pbx_capi_nulliflist_lock(void);
|
||||
/*!
|
||||
\brief cc_mutex_unlock(&nullif_lock)
|
||||
*/
|
||||
void pbx_capi_nulliflist_unlock(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,8 +50,16 @@ echo "#define CHAN_CAPI_CONFIG_H" >>$CONFIGFILE
|
|||
echo >>$CONFIGFILE
|
||||
|
||||
case "$AVERSIONNUM" in
|
||||
108*)
|
||||
echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
|
||||
echo "#define CC_AST_HAS_VERSION_1_8" >>$CONFIGFILE
|
||||
echo "#define CC_AST_HAS_EVENT_MWI" >>$CONFIGFILE
|
||||
echo " * found Asterisk version 1.8"
|
||||
VER=1_8
|
||||
;;
|
||||
106*)
|
||||
echo "#define CC_AST_HAS_VERSION_1_6" >>$CONFIGFILE
|
||||
echo "#define CC_AST_HAS_EVENT_MWI" >>$CONFIGFILE
|
||||
echo " * found Asterisk version 1.6"
|
||||
VER=1_6
|
||||
;;
|
||||
|
@ -235,6 +243,15 @@ check_version_onesix()
|
|||
echo "#undef CC_AST_HAS_RTP_ENGINE_H" >>$CONFIGFILE
|
||||
echo " * no rtp_engine.h"
|
||||
fi
|
||||
if [ -f $INCLUDEDIR/netsock2.h ]; then
|
||||
if grep -q "struct ast_sockaddr " $INCLUDEDIR/netsock2.h; then
|
||||
echo "#define CC_AST_HAS_AST_SOCKADDR" >>$CONFIGFILE
|
||||
echo " * found ast_sockaddr structure"
|
||||
else
|
||||
echo "#undef CC_AST_HAS_AST_SOCKADDR" >>$CONFIGFILE
|
||||
echo " * no ast_sockaddr structure"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case $VER in
|
||||
|
@ -250,6 +267,10 @@ case $VER in
|
|||
echo "Using Asterisk 1.6 API"
|
||||
check_version_onesix
|
||||
;;
|
||||
1_8)
|
||||
echo "Using Asterisk 1.8 API"
|
||||
check_version_onesix
|
||||
;;
|
||||
*)
|
||||
echo >&2 "Asterisk version invalid."
|
||||
exit 1
|
||||
|
|
|
@ -0,0 +1,675 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Implements to access Diva management file system
|
||||
*
|
||||
* \par Access to Diva hardware state
|
||||
* divalogd captures information from Diva management and exports
|
||||
* it CVS file format.
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "divastreaming/platform.h"
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "dlist.h"
|
||||
#include "divastatus_parameters.h"
|
||||
#include "divastatus_ifc.h"
|
||||
#include "divastatus.h"
|
||||
#ifdef CC_USE_INOTIFY
|
||||
#include <fcntl.h>
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
typedef const char* pcchar;
|
||||
|
||||
static pcchar DIVA_STATUS_PATH = "/usr/lib/eicon/divas/registry/ifc";
|
||||
static pcchar DIVA_STATUS_FILE = "ifcstate";
|
||||
static pcchar DIVA_INFO_FILE = "info";
|
||||
static pcchar DIVA_CONFIG_FILE = "info/Config";
|
||||
static pcchar DIVA_SERIAL_FILE = "serial";
|
||||
static pcchar DIVA_READ_ALARM_FILE = "info/Red Alarm";
|
||||
static pcchar DIVA_YELLOW_ALARM_FILE = "info/Yellow Alarm";
|
||||
static pcchar DIVA_BLUE_ALARM_FILE = "info/Blue Alarm";
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
struct _diva_status_ifc;
|
||||
static int diva_status_active(void);
|
||||
static int diva_status_get_controller_state(int controller, diva_status_ifc_state_t *state);
|
||||
static char* diva_status_read_file(unsigned int controller, const char* fileName);
|
||||
static void diva_status_create_wd(int* wd, int controller, const char* fileName, int isDir);
|
||||
static diva_status_interface_state_t diva_status_get_interface_state_from_idi_state (const diva_status_ifc_state_t* state);
|
||||
static diva_status_hardware_state_t diva_status_get_hw_state_from_idi_state (const diva_status_ifc_state_t* state);
|
||||
static int diva_status_map_CAPI2XDI(int capiController);
|
||||
static void diva_status_process_event(struct _diva_status_ifc *controllerState, int initialStateIndex, int newStateIndex);
|
||||
#ifdef CC_USE_INOTIFY
|
||||
static pcchar DIVA_DIVA_FS_PATH = "/usr/lib/eicon/divas/registry/ifc";
|
||||
static void diva_status_cleanup_wd(int wd);
|
||||
static int divaFsWd = -1; /*! \brief Diva fs state */
|
||||
#endif
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static
|
||||
#endif
|
||||
char diva_status_ifc_state_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " ifcstate\n"
|
||||
" Show info about interfaces.\n";
|
||||
|
||||
|
||||
static int inotifyFd = -1; /*! \brief inotify descriptor */
|
||||
static diva_entity_queue_t controller_q; /*! \brief Active controllers. \note List changed only while CAPI thread is not running */
|
||||
|
||||
typedef struct _diva_status_ifc {
|
||||
diva_entity_link_t link;
|
||||
int capiController;
|
||||
int idiController;
|
||||
diva_status_ifc_state_t state[2];
|
||||
int currentState;
|
||||
int ifstateWd;
|
||||
int infoWd;
|
||||
diva_status_changed_cb_proc_t status_changed_notify_proc; /*! \brief Notify about interface state change */
|
||||
diva_hwstatus_changed_cb_proc_t hw_status_changed_notify_proc; /*! \brief Notify about hardware state change */
|
||||
time_t changeTime; /*! \brief Time interface state changed */
|
||||
time_t unavailableChangeTime; /*! \brief Time interface state changed to unavailable */
|
||||
time_t hwChangeTime; /*! \brief Time hardware state changed */
|
||||
time_t unavailableHwChangeTime; /*! \brief Time hardware state changed to unavailable */
|
||||
} diva_status_ifc_t;
|
||||
|
||||
diva_status_interface_state_t diva_status_init_interface(int controller,
|
||||
diva_status_hardware_state_t* hwState,
|
||||
diva_status_changed_cb_proc_t fn,
|
||||
diva_hwstatus_changed_cb_proc_t hwfn)
|
||||
{
|
||||
int idiController = diva_status_map_CAPI2XDI(controller);
|
||||
diva_status_ifc_t* controllerState = idiController > 0 ? (ast_malloc(sizeof(*controllerState))) : 0;
|
||||
diva_status_interface_state_t ret = DivaStatusInterfaceStateNotAvailable;
|
||||
|
||||
if (controllerState != 0) {
|
||||
controllerState->capiController = controller;
|
||||
controllerState->idiController = idiController;
|
||||
controllerState->status_changed_notify_proc = fn;
|
||||
controllerState->hw_status_changed_notify_proc = hwfn;
|
||||
controllerState->ifstateWd = -1;
|
||||
controllerState->infoWd = -1;
|
||||
diva_status_create_wd(&controllerState->ifstateWd, idiController, DIVA_STATUS_FILE, 0);
|
||||
diva_status_create_wd(&controllerState->infoWd, idiController, DIVA_INFO_FILE, 1);
|
||||
controllerState->currentState = 0;
|
||||
controllerState->changeTime = time(NULL);
|
||||
diva_status_get_controller_state(idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_q_add_tail(&controller_q, &controllerState->link);
|
||||
ret = diva_status_get_interface_state_from_idi_state(&controllerState->state[controllerState->currentState]);
|
||||
*hwState = diva_status_get_hw_state_from_idi_state(&controllerState->state[controllerState->currentState]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void diva_status_cleanup_interface (int controller)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
|
||||
if (controllerState->capiController == controller) {
|
||||
diva_q_remove(&controller_q, link);
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (controllerState->ifstateWd >= 0)
|
||||
inotify_rm_watch(inotifyFd, controllerState->ifstateWd);
|
||||
if (controllerState->infoWd >= 0)
|
||||
inotify_rm_watch(inotifyFd, controllerState->infoWd);
|
||||
#endif
|
||||
ast_free (controllerState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (diva_q_get_head(&controller_q) == 0) {
|
||||
if (divaFsWd >= 0) {
|
||||
inotify_rm_watch(inotifyFd, divaFsWd);
|
||||
divaFsWd = -1;
|
||||
}
|
||||
if (inotifyFd >= 0) {
|
||||
close(inotifyFd);
|
||||
inotifyFd = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int diva_status_get_waitable_object(void)
|
||||
{
|
||||
return inotifyFd;
|
||||
}
|
||||
|
||||
void diva_status_process_events(void)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
/*
|
||||
Polling
|
||||
*/
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
if ((controllerState->ifstateWd < 0) || (controllerState->infoWd < 0)) {
|
||||
int currentState = controllerState->currentState;
|
||||
diva_status_create_wd(&controllerState->ifstateWd, controllerState->idiController, DIVA_STATUS_FILE, 0);
|
||||
diva_status_create_wd(&controllerState->infoWd, controllerState->idiController, DIVA_INFO_FILE, 1);
|
||||
controllerState->currentState = (controllerState->currentState + 1) % 2;
|
||||
diva_status_get_controller_state(controllerState->idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_status_process_event(controllerState, currentState, controllerState->currentState);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Events
|
||||
*/
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (inotifyFd >= 0 && divaFsWd >= 0) {
|
||||
unsigned char buffer[1024];
|
||||
int length;
|
||||
int i;
|
||||
|
||||
while ((length = read(inotifyFd, buffer, sizeof(buffer))) > 0) {
|
||||
i = 0;
|
||||
while (i < length) {
|
||||
struct inotify_event *event = (struct inotify_event*)&buffer[i];
|
||||
|
||||
if ((event->mask & (IN_IGNORED|IN_DELETE_SELF|IN_UNMOUNT|IN_Q_OVERFLOW)) != 0) {
|
||||
diva_status_cleanup_wd((event->mask & IN_IGNORED) == 0 ? event->wd : -1);
|
||||
break;
|
||||
}
|
||||
if (event->wd != divaFsWd) {
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
if ((controllerState->ifstateWd == event->wd) || (controllerState->infoWd == event->wd)) {
|
||||
int currentState = controllerState->currentState;
|
||||
controllerState->currentState = (controllerState->currentState + 1) % 2;
|
||||
diva_status_get_controller_state(controllerState->idiController, &controllerState->state[controllerState->currentState]);
|
||||
diva_status_process_event(controllerState, currentState, controllerState->currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i += sizeof(*event) + event->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CC_USE_INOTIFY
|
||||
static void diva_status_cleanup_wd(int wd)
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
|
||||
if ((controllerState->ifstateWd >= 0) && (wd != controllerState->ifstateWd)) {
|
||||
inotify_rm_watch(inotifyFd, controllerState->ifstateWd);
|
||||
}
|
||||
controllerState->ifstateWd = -1;
|
||||
if ((controllerState->infoWd >= 0) && (wd != controllerState->infoWd)) {
|
||||
inotify_rm_watch(inotifyFd, controllerState->infoWd);
|
||||
}
|
||||
controllerState->infoWd = -1;
|
||||
}
|
||||
|
||||
if ((divaFsWd >= 0) && (wd != divaFsWd)) {
|
||||
inotify_rm_watch(inotifyFd, divaFsWd);
|
||||
}
|
||||
divaFsWd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void diva_status_process_event(diva_status_ifc_t *controllerState, int initialStateIndex, int newStateIndex)
|
||||
{
|
||||
diva_status_ifc_state_t* initialState = &controllerState->state[initialStateIndex];
|
||||
diva_status_ifc_state_t* newState = &controllerState->state[newStateIndex];
|
||||
diva_status_interface_state_t initialIfcState = diva_status_get_interface_state_from_idi_state (initialState);
|
||||
diva_status_interface_state_t newIfcState = diva_status_get_interface_state_from_idi_state (newState);
|
||||
diva_status_hardware_state_t initalHwState = diva_status_get_hw_state_from_idi_state(initialState);
|
||||
diva_status_hardware_state_t newHwState = diva_status_get_hw_state_from_idi_state(newState);
|
||||
time_t t = time(NULL);
|
||||
|
||||
if (initialIfcState != newIfcState) {
|
||||
controllerState->changeTime = t;
|
||||
|
||||
if (newIfcState == DivaStatusInterfaceStateERROR)
|
||||
controllerState->unavailableChangeTime = t;
|
||||
|
||||
controllerState->status_changed_notify_proc(controllerState->capiController, newIfcState);
|
||||
}
|
||||
|
||||
if (initalHwState != newHwState) {
|
||||
controllerState->hwChangeTime = t;
|
||||
|
||||
if (newHwState == DivaStatusHardwareStateERROR)
|
||||
controllerState->unavailableHwChangeTime = t;
|
||||
|
||||
controllerState->hw_status_changed_notify_proc(controllerState->capiController, newHwState);
|
||||
}
|
||||
}
|
||||
|
||||
static void diva_status_create_wd(int* wd, int controller, const char* fileName, int isDir)
|
||||
{
|
||||
#ifdef CC_USE_INOTIFY
|
||||
if (inotifyFd < 0) {
|
||||
inotifyFd = inotify_init();
|
||||
if (inotifyFd >= 0)
|
||||
fcntl(inotifyFd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
if (inotifyFd >= 0 && divaFsWd < 0) {
|
||||
divaFsWd = inotify_add_watch (inotifyFd, DIVA_DIVA_FS_PATH, IN_DELETE_SELF | IN_UNMOUNT | IN_IGNORED);
|
||||
}
|
||||
|
||||
if (*wd >= 0)
|
||||
return;
|
||||
|
||||
if (inotifyFd >= 0 && divaFsWd >= 0) {
|
||||
int name_len = strlen(DIVA_STATUS_PATH) + strlen(fileName) + 32;
|
||||
char name[name_len];
|
||||
|
||||
snprintf(name, name_len, "%s/adapter%u/%s", DIVA_STATUS_PATH, controller, fileName);
|
||||
name[name_len-1] = 0;
|
||||
|
||||
*wd = inotify_add_watch (inotifyFd, name,
|
||||
IN_CLOSE_WRITE | IN_DELETE_SELF | IN_IGNORED | ((isDir != 0) ? IN_DELETE : 0));
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
*wd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Check divalogd is available
|
||||
*/
|
||||
static int diva_status_active(void)
|
||||
{
|
||||
struct stat v;
|
||||
|
||||
return ((stat(DIVA_STATUS_PATH, &v) == 0 && S_ISDIR(v.st_mode) != 0) ? 0 : -1);
|
||||
}
|
||||
|
||||
static char* diva_status_read_file(unsigned int controller, const char* fileName)
|
||||
{
|
||||
int name_len = strlen(DIVA_STATUS_PATH) + strlen(fileName) + 32;
|
||||
char name[name_len];
|
||||
struct stat v;
|
||||
int fd;
|
||||
int length;
|
||||
char *data, *p;
|
||||
|
||||
snprintf(name, name_len, "%s/adapter%u/%s", DIVA_STATUS_PATH, controller, fileName);
|
||||
name[name_len-1] = 0;
|
||||
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
if (fstat(fd, &v) != 0 || v.st_size == 0) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = MIN(v.st_size, 16U*1024U);
|
||||
|
||||
data = ast_malloc(length+1);
|
||||
if (data == 0) {
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(fd, data, length) != length) {
|
||||
ast_free(data);
|
||||
close(fd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
data[length] = 0;
|
||||
|
||||
while (((p = strchr(data, '\n')) != 0) || ((p = strchr(data, '\r')))) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
return (data);
|
||||
}
|
||||
|
||||
static int diva_status_get_controller_state(int controller, diva_status_ifc_state_t *state)
|
||||
{
|
||||
char *data, *p;
|
||||
int i, pri;
|
||||
const char* v;
|
||||
|
||||
memset (state, 0x00, sizeof(*state));
|
||||
state->ifcType = DivaStatusIfcNotPri;
|
||||
state->hwState = DivaStatusHwStateUnknown;
|
||||
state->ifcL1State = DivaStatusIfcL2DoNotApply;
|
||||
state->ifcL2State = DivaStatusIfcL2DoNotApply;
|
||||
|
||||
if (diva_status_active() != 0)
|
||||
return -1;
|
||||
|
||||
if ((data = diva_status_read_file(controller, DIVA_CONFIG_FILE)) == 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0, pri = 0, p = data, v = strsep(&p, ",");
|
||||
v != 0 && i < DivaStateIfcConfig_Max;
|
||||
v = strsep(&p, ","), i++) {
|
||||
if (v[0] == '\'' && v[strlen(v)-1] != '\'') {
|
||||
const char *tmp;
|
||||
do {
|
||||
if ((p != 0) && (*p != 0))
|
||||
p[-1] = ',';
|
||||
tmp = strsep (&p, ",");
|
||||
} while ((tmp != 0) && (tmp[strlen(tmp)-1] != '\''));
|
||||
}
|
||||
|
||||
switch ((diva_state_ifc_config_parameters_t)i) {
|
||||
case DivaStateIfcConfig_TYPE:
|
||||
pri += (strcmp ("PRI", v) == 0);
|
||||
break;
|
||||
|
||||
case DivaStateIfcConfig_PRI:
|
||||
pri += (strcmp ("'YES'", v) == 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ast_free(data);
|
||||
|
||||
state->ifcType = (pri == 2) ? DivaStatusIfcPri : DivaStatusIfcNotPri;
|
||||
|
||||
if ((data = diva_status_read_file(controller, DIVA_STATUS_FILE)) == 0)
|
||||
return (-1);
|
||||
|
||||
for (i = 0, p = data, v = strsep (&p, ","); v != 0 && i < (int)DivaStateIfcState_Max; v = strsep (&p, ","), i++) {
|
||||
if (v[0] == '\'' && v[strlen(v)-1] != '\'') {
|
||||
const char *tmp;
|
||||
do {
|
||||
if ((p != 0) && (*p != 0))
|
||||
p[-1] = ',';
|
||||
tmp = strsep (&p, ",");
|
||||
} while ((tmp != 0) && (tmp[strlen(tmp)-1] != '\''));
|
||||
}
|
||||
|
||||
switch ((diva_state_ifcstate_parameters_t)i) {
|
||||
case DivaStateIfcState_LAYER1_STATE:
|
||||
if (state->ifcType == DivaStatusIfcPri) {
|
||||
state->ifcL1State = (strcmp ("'Activated'", v) == 0) ? DivaStatusIfcL1OK : DivaStatusIfcL1Error;
|
||||
}
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_LAYER2_STATE:
|
||||
if (state->ifcType == DivaStatusIfcPri) {
|
||||
state->ifcL2State = (strcmp ("'Layer2 UP'", v) == 0) ? DivaStatusIfcL2OK : DivaStatusIfcL2Error;
|
||||
}
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_D1_X_FRAMES:
|
||||
state->ifcTxDStatistics.Frames = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D1_X_BYTES:
|
||||
state->ifcTxDStatistics.Bytes = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D1_X_ERRORS:
|
||||
state->ifcTxDStatistics.Errors = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D1_R_FRAMES:
|
||||
state->ifcRxDStatistics.Frames = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D1_R_BYTES:
|
||||
state->ifcRxDStatistics.Bytes = (unsigned int)atol(v);
|
||||
break;
|
||||
case DivaStateIfcState_D1_R_ERRORS:
|
||||
state->ifcRxDStatistics.Errors = (unsigned int)atol(v);
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_MAX_TEMPERATURE:
|
||||
state->maxTemperature = (unsigned int)atoi(v);
|
||||
break;
|
||||
case DivaStateIfcState_TEMPERATURE:
|
||||
state->currentTemperature = (unsigned int)atoi(v);
|
||||
break;
|
||||
|
||||
case DivaStateIfcState_HARDWARE_STATE:
|
||||
if (strcmp("'Active'", v) == 0)
|
||||
state->hwState = DivaStateHwStateActive;
|
||||
else if (strcmp("'Inactive'", v) == 0)
|
||||
state->hwState = DivaStateHwStateInactive;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ast_free (data);
|
||||
|
||||
if ((data = diva_status_read_file(controller, DIVA_READ_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Red = strcmp("TRUE", data) == 0;
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_YELLOW_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Yellow = strcmp("TRUE", data) == 0;
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_BLUE_ALARM_FILE)) != 0) {
|
||||
state->ifcAlarms.Blue = strcmp("TRUE", data) == 0;
|
||||
ast_free(data);
|
||||
}
|
||||
if ((data = diva_status_read_file(controller, DIVA_SERIAL_FILE)) != 0) {
|
||||
state->serialNumber = (unsigned int)(atol(data)) & 0x00ffffff;
|
||||
ast_free(data);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
chan_capi interface
|
||||
*/
|
||||
diva_status_interface_state_t diva_status_get_interface_state(int controller)
|
||||
{
|
||||
diva_status_ifc_state_t state;
|
||||
int ret;
|
||||
|
||||
ret = diva_status_get_controller_state(controller, &state);
|
||||
|
||||
if ((ret != 0) ||
|
||||
(state.ifcType != DivaStatusIfcPri) ||
|
||||
(state.ifcL1State == DivaStatusIfcL2DoNotApply) ||
|
||||
(state.hwState == DivaStatusHwStateUnknown)) {
|
||||
return (DivaStatusInterfaceStateNotAvailable);
|
||||
}
|
||||
|
||||
if ((state.ifcAlarms.Red == 0) &&
|
||||
(state.ifcAlarms.Yellow == 0) &&
|
||||
(state.ifcAlarms.Blue == 0) &&
|
||||
(state.hwState == DivaStateHwStateActive) &&
|
||||
(state.ifcL1State == DivaStatusIfcL1OK)) {
|
||||
return DivaStatusInterfaceStateOK;
|
||||
}
|
||||
|
||||
return DivaStatusInterfaceStateERROR;
|
||||
}
|
||||
|
||||
static diva_status_interface_state_t diva_status_get_interface_state_from_idi_state(const diva_status_ifc_state_t* state)
|
||||
{
|
||||
if ((state->ifcType != DivaStatusIfcPri) ||
|
||||
(state->ifcL1State == DivaStatusIfcL2DoNotApply) ||
|
||||
(state->hwState == DivaStatusHwStateUnknown)) {
|
||||
return (DivaStatusInterfaceStateNotAvailable);
|
||||
}
|
||||
|
||||
if ((state->ifcAlarms.Red == 0) &&
|
||||
(state->ifcAlarms.Yellow == 0) &&
|
||||
(state->ifcAlarms.Blue == 0) &&
|
||||
(state->hwState == DivaStateHwStateActive) &&
|
||||
(state->ifcL1State == DivaStatusIfcL1OK)) {
|
||||
return DivaStatusInterfaceStateOK;
|
||||
}
|
||||
|
||||
return DivaStatusInterfaceStateERROR;
|
||||
}
|
||||
|
||||
static diva_status_hardware_state_t diva_status_get_hw_state_from_idi_state(const diva_status_ifc_state_t* state)
|
||||
{
|
||||
switch(state->hwState) {
|
||||
case DivaStateHwStateActive:
|
||||
return (DivaStatusHardwareStateOK);
|
||||
|
||||
case DivaStateHwStateInactive:
|
||||
return (DivaStatusHardwareStateERROR);
|
||||
|
||||
case DivaStatusHwStateUnknown:
|
||||
default:
|
||||
return (DivaStatusHardwareStateUnknown);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Map CAPI controller to Diva hardware
|
||||
|
||||
\note In most cases chan_capi uses 1:1 mappimg
|
||||
between CAPI controller and Diva hardware
|
||||
|
||||
\todo Read CAPI2DIva mapping table from CAPI
|
||||
*/
|
||||
static int diva_status_map_CAPI2XDI(int capiController)
|
||||
{
|
||||
return ((capiController > 0) ? capiController : -1);
|
||||
}
|
||||
|
||||
int diva_status_available(void)
|
||||
{
|
||||
return (diva_status_active());
|
||||
}
|
||||
|
||||
const char* diva_status_interface_state_name(diva_status_interface_state_t state)
|
||||
{
|
||||
switch(state) {
|
||||
case DivaStatusInterfaceStateOK:
|
||||
return "active";
|
||||
|
||||
case DivaStatusInterfaceStateERROR:
|
||||
return "inactive";
|
||||
|
||||
case DivaStatusInterfaceStateNotAvailable:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* diva_status_hw_state_name(diva_status_hardware_state_t hwState)
|
||||
{
|
||||
switch(hwState) {
|
||||
case DivaStatusHardwareStateOK:
|
||||
return "active";
|
||||
|
||||
case DivaStatusHardwareStateERROR:
|
||||
return "not running";
|
||||
|
||||
case DivaStatusHardwareStateUnknown:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
char *pbxcli_capi_ifc_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
int pbxcli_capi_ifc_status(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
diva_entity_link_t* link;
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " ifcstate";
|
||||
e->usage = diva_status_ifc_state_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
|
||||
if (argc != 2)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
if ( diva_q_get_head(&controller_q) == NULL) {
|
||||
ast_cli(fd, "There are no interraces in " CC_MESSAGE_NAME " instance.\n");
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ast_cli(fd, CC_MESSAGE_NAME " interfaces\n");
|
||||
ast_cli(fd, "%s %-9s%-4s%-4s%-4s%-7s%-5s%8s%12s%12s%12s%12s\n",
|
||||
"INTERFACE", "State", "L1", "L2", "RED", "YELLOW", "BLUE", "D-Rx-Frames", "D-Rx-Bytes","D-Tx-Frames", "D-Tx-Bytes", "D-Errors");
|
||||
|
||||
for (link = diva_q_get_head(&controller_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_status_ifc_t *controllerState = DIVAS_CONTAINING_RECORD(link, diva_status_ifc_t, link);
|
||||
diva_status_ifc_state_t* state = &controllerState->state[controllerState->currentState];
|
||||
ast_cli(fd, "ISDN%-3d%-2s %-9s%-4s%-4s%-4s%-7s%-3s %12d %11d %11d %11d %11d\n",
|
||||
controllerState->capiController, "",
|
||||
diva_status_interface_state_name(diva_status_get_interface_state_from_idi_state (state)),
|
||||
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
|
||||
(state->ifcL1State == DivaStatusIfcL1OK ? "On" : "Off") : "-",
|
||||
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
|
||||
(state->ifcL2State == DivaStatusIfcL2OK ? "On" : "Off") : "-",
|
||||
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
|
||||
(state->ifcAlarms.Red != 0 ? "On" : "Off") : "-",
|
||||
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
|
||||
(state->ifcAlarms.Yellow != 0 ? "On" : "Off") : "-",
|
||||
((state->ifcType == DivaStatusIfcPri) && (state->hwState == DivaStatusHardwareStateOK)) ?
|
||||
(state->ifcAlarms.Blue != 0 ? "On" : "Off") : "-",
|
||||
state->ifcRxDStatistics.Frames, state->ifcRxDStatistics.Bytes,
|
||||
state->ifcTxDStatistics.Frames, state->ifcTxDStatistics.Bytes,
|
||||
state->ifcRxDStatistics.Errors + state->ifcTxDStatistics.Errors
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return CLI_SUCCESS;
|
||||
#else
|
||||
return RESULT_SUCCESS;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Declares interface to access diva management file system
|
||||
*/
|
||||
|
||||
#ifndef __DIVA_STATUS_H__
|
||||
#define __DIVA_STATUS_H__
|
||||
|
||||
typedef enum _diva_status_ifc_type {
|
||||
DivaStatusIfcNotPri = 0,
|
||||
DivaStatusIfcPri,
|
||||
DivaStatusIfcBri,
|
||||
DivaStatusIfcAnalog
|
||||
} diva_status_ifc_type_t;
|
||||
|
||||
typedef struct _diva_status_ifc_alarms {
|
||||
int Red;
|
||||
int Blue;
|
||||
int Yellow;
|
||||
} diva_status_ifc_alarms_t;
|
||||
|
||||
typedef enum _diva_status_ifc_l1_state {
|
||||
DivaStatusIfcL1DoNotApply = 0,
|
||||
DivaStatusIfcL1OK,
|
||||
DivaStatusIfcL1Error
|
||||
} diva_status_ifc_l1_state_t;
|
||||
|
||||
typedef enum _diva_status_ifc_l2_state {
|
||||
DivaStatusIfcL2DoNotApply = 0,
|
||||
DivaStatusIfcL2OK,
|
||||
DivaStatusIfcL2Error
|
||||
} diva_status_ifc_l2_state_t;
|
||||
|
||||
typedef enum _diva_status_ifc_hw_state {
|
||||
DivaStatusHwStateUnknown = 0,
|
||||
DivaStateHwStateActive = 1,
|
||||
DivaStateHwStateInactive = 2
|
||||
} diva_status_ifc_hw_state_t;
|
||||
|
||||
typedef struct _diva_status_ifc_statistics {
|
||||
unsigned int Frames;
|
||||
unsigned int Bytes;
|
||||
unsigned int Errors;
|
||||
} diva_status_ifc_statistics_t;
|
||||
|
||||
typedef struct _diva_status_ifc_state {
|
||||
diva_status_ifc_type_t ifcType;
|
||||
diva_status_ifc_hw_state_t hwState;
|
||||
diva_status_ifc_alarms_t ifcAlarms;
|
||||
diva_status_ifc_l1_state_t ifcL1State;
|
||||
diva_status_ifc_l2_state_t ifcL2State;
|
||||
diva_status_ifc_statistics_t ifcRxDStatistics;
|
||||
diva_status_ifc_statistics_t ifcTxDStatistics;
|
||||
unsigned int serialNumber;
|
||||
unsigned int maxTemperature;
|
||||
unsigned int currentTemperature;
|
||||
} diva_status_ifc_state_t;
|
||||
|
||||
#define DIVA_STATUS_EVENT_L1 0x00000001U
|
||||
#define DIVA_STATUS_EVENT_L2 0x00000002U
|
||||
#define DIVA_STATUS_EVENT_ALARMS 0x00000004U
|
||||
#define DIVA_STATUS_EVENT_STATISTICS 0x00000008U
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Interface to chan_capi
|
||||
*/
|
||||
|
||||
#ifndef __DIVA_STATUS_IFC_H__
|
||||
#define __DIVA_STATUS_IFC_H__
|
||||
|
||||
typedef enum _diva_status_interface_state {
|
||||
DivaStatusInterfaceStateNotAvailable = 0,
|
||||
DivaStatusInterfaceStateOK = 1,
|
||||
DivaStatusInterfaceStateERROR = -1,
|
||||
} diva_status_interface_state_t;
|
||||
|
||||
typedef enum _diva_status_hardware_state {
|
||||
DivaStatusHardwareStateUnknown = 0, /*! /brief divalog is not running or old version of divalog */
|
||||
DivaStatusHardwareStateOK = 1, /*! /brief hardware status veriefied and OK */
|
||||
DivaStatusHardwareStateERROR = -1 /*! /brief hardware status verified and not OK */
|
||||
} diva_status_hardware_state_t;
|
||||
|
||||
/*!
|
||||
\brief Check if Diva interface is available
|
||||
*/
|
||||
int diva_status_available(void);
|
||||
|
||||
typedef void (*diva_status_changed_cb_proc_t)(int controller, diva_status_interface_state_t state);
|
||||
typedef void (*diva_hwstatus_changed_cb_proc_t)(int controller, diva_status_hardware_state_t hwstate);
|
||||
|
||||
/*!
|
||||
\brief activate event based status notifications
|
||||
|
||||
\param fn called if interface state changes, includes hardware state
|
||||
|
||||
\param hwfn called if hardware status changed, hardware state only, used for processing of IP media streams by resource/chat commands
|
||||
*/
|
||||
diva_status_interface_state_t diva_status_init_interface(int controller,
|
||||
diva_status_hardware_state_t* hwState,
|
||||
diva_status_changed_cb_proc_t fn,
|
||||
diva_hwstatus_changed_cb_proc_t hwfn);
|
||||
/*!
|
||||
\brief deactivate event based status notifications
|
||||
*/
|
||||
void diva_status_cleanup_interface(int controller);
|
||||
/*!
|
||||
\brief retrieve file handle to be used in async
|
||||
I/O operations
|
||||
*/
|
||||
int diva_status_get_waitable_object(void);
|
||||
/*!
|
||||
\brief process status change events
|
||||
*/
|
||||
void diva_status_process_events(void);
|
||||
|
||||
/*!
|
||||
\brief Retrieve state of interface
|
||||
DivaStatusInterfaceStateNotAvailable - ignore state
|
||||
DivaStatusInterfaceStateOK - interface state verified and OK
|
||||
DivaStatusInterfaceStateERROR - interface state verified and
|
||||
can not be used to create calls
|
||||
*/
|
||||
diva_status_interface_state_t diva_status_get_interface_state(int controller);
|
||||
|
||||
const char* diva_status_interface_state_name(diva_status_interface_state_t state);
|
||||
const char* diva_status_hw_state_name(diva_status_hardware_state_t hwState);
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
char *pbxcli_capi_ifc_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
||||
#else
|
||||
int pbxcli_capi_ifc_status(int fd, int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#define CC_CLI_TEXT_IFC_STATUSINFO "Show " CC_MESSAGE_BIGNAME " interface info"
|
||||
#ifndef CC_AST_HAS_VERSION_1_6
|
||||
extern char diva_status_ifc_state_usage[];
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DIVA_STATUS_PARAMETERS_H__
|
||||
#define __DIVA_STATUS_PARAMETERS_H__
|
||||
|
||||
/*! \brief ifcstate
|
||||
*/
|
||||
typedef enum _diva_state_ifcstate_parameters {
|
||||
DivaStateIfcState_LAYER1_STATE = 0,
|
||||
DivaStateIfcState_LAYER2_STATE,
|
||||
DivaStateIfcState_INC_CALLS,
|
||||
DivaStateIfcState_INC_CONNECTED,
|
||||
DivaStateIfcState_INC_USER_BUSY,
|
||||
DivaStateIfcState_INC_CALL_REJECTED,
|
||||
DivaStateIfcState_INC_WRONG_NUMBER,
|
||||
DivaStateIfcState_INC_INCOMPATIBLE_DST,
|
||||
DivaStateIfcState_INC_OUT_OF_ORDER,
|
||||
DivaStateIfcState_INC_IGNORED,
|
||||
DivaStateIfcState_OUT_CALLS,
|
||||
DivaStateIfcState_OUT_CONNECTED,
|
||||
DivaStateIfcState_OUT_USER_BUSY,
|
||||
DivaStateIfcState_OUT_NO_ANSWER,
|
||||
DivaStateIfcState_OUT_WRONG_NUMBER,
|
||||
DivaStateIfcState_OUT_CALL_REJECTED,
|
||||
DivaStateIfcState_OUT_OTHER_FAILURES,
|
||||
DivaStateIfcState_MDM_DISC_NORMAL,
|
||||
DivaStateIfcState_MDM_DISC_UNSPECIFIED,
|
||||
DivaStateIfcState_MDM_DISC_BUSY_TONE,
|
||||
DivaStateIfcState_MDM_DISC_CONGESTION,
|
||||
DivaStateIfcState_MDM_DISC_CARR_WAIT,
|
||||
DivaStateIfcState_MDM_DISC_TRN_TIMEOUT,
|
||||
DivaStateIfcState_MDM_DISC_INCOMPAT,
|
||||
DivaStateIfcState_MDM_DISC_FRAME_REJ,
|
||||
DivaStateIfcState_MDM_DISC_V42BIS,
|
||||
DivaStateIfcState_FAX_DISC_NORMAL,
|
||||
DivaStateIfcState_FAX_DISC_NOT_IDENT,
|
||||
DivaStateIfcState_FAX_DISC_NO_RESPONSE,
|
||||
DivaStateIfcState_FAX_DISC_RETRIES,
|
||||
DivaStateIfcState_FAX_DISC_UNEXP_MSG,
|
||||
DivaStateIfcState_FAX_DISC_NO_POLLING,
|
||||
DivaStateIfcState_FAX_DISC_TRAINING,
|
||||
DivaStateIfcState_FAX_DISC_UNEXPECTED,
|
||||
DivaStateIfcState_FAX_DISC_APPLICATION,
|
||||
DivaStateIfcState_FAX_DISC_INCOMPAT,
|
||||
DivaStateIfcState_FAX_DISC_NO_COMMAND,
|
||||
DivaStateIfcState_FAX_DISC_LONG_MSG,
|
||||
DivaStateIfcState_FAX_DISC_SUPERVISOR,
|
||||
DivaStateIfcState_FAX_DISC_SUB_SEP_PWD,
|
||||
DivaStateIfcState_FAX_DISC_INVALID_MSG,
|
||||
DivaStateIfcState_FAX_DISC_PAGE_CODING,
|
||||
DivaStateIfcState_FAX_DISC_APP_TIMEOUT,
|
||||
DivaStateIfcState_FAX_DISC_UNSPECIFIED,
|
||||
DivaStateIfcState_B1_X_FRAMES,
|
||||
DivaStateIfcState_B1_X_BYTES,
|
||||
DivaStateIfcState_B1_X_ERRORS,
|
||||
DivaStateIfcState_B1_R_FRAMES,
|
||||
DivaStateIfcState_B1_R_BYTES,
|
||||
DivaStateIfcState_B1_R_ERRORS,
|
||||
DivaStateIfcState_B2_X_FRAMES,
|
||||
DivaStateIfcState_B2_X_BYTES,
|
||||
DivaStateIfcState_B2_X_ERRORS,
|
||||
DivaStateIfcState_B2_R_FRAMES,
|
||||
DivaStateIfcState_B2_R_BYTES,
|
||||
DivaStateIfcState_B2_R_ERRORS,
|
||||
DivaStateIfcState_D1_X_FRAMES,
|
||||
DivaStateIfcState_D1_X_BYTES,
|
||||
DivaStateIfcState_D1_X_ERRORS,
|
||||
DivaStateIfcState_D1_R_FRAMES,
|
||||
DivaStateIfcState_D1_R_BYTES,
|
||||
DivaStateIfcState_D1_R_ERRORS,
|
||||
DivaStateIfcState_D2_X_FRAMES,
|
||||
DivaStateIfcState_D2_X_BYTES,
|
||||
DivaStateIfcState_D2_X_ERRORS,
|
||||
DivaStateIfcState_D2_R_FRAMES,
|
||||
DivaStateIfcState_D2_R_BYTES,
|
||||
DivaStateIfcState_D2_R_ERRORS,
|
||||
DivaStateIfcState_INITIAL_TEMPERATURE,
|
||||
DivaStateIfcState_MIN_TEMPERATURE,
|
||||
DivaStateIfcState_MAX_TEMPERATURE,
|
||||
DivaStateIfcState_TEMPERATURE,
|
||||
DivaStateIfcState_DSPSTATE,
|
||||
DivaStateIfcState_FAX_TX_PAGES_TOTAL,
|
||||
DivaStateIfcState_FAX_TX_PAGES_RETRAIN,
|
||||
DivaStateIfcState_FAX_TX_PAGES_REJECT,
|
||||
DivaStateIfcState_FAX_RX_PAGES_TOTAL,
|
||||
DivaStateIfcState_FAX_RX_PAGES_RETRAIN,
|
||||
DivaStateIfcState_FAX_RX_PAGES_REJECT,
|
||||
DivaStateIfcState_OUT_ABANDONED,
|
||||
DivaStateIfcState_IN_ABANDONED,
|
||||
DivaStateIfcState_HARDWARE_STATE,
|
||||
DivaStateIfcState_Max
|
||||
} diva_state_ifcstate_parameters_t;
|
||||
|
||||
typedef enum diva_state_ifc_config_parameters {
|
||||
DivaStateIfcConfig_TYPE = 0,
|
||||
DivaStateIfcConfig_CHANNELS,
|
||||
DivaStateIfcConfig_PROTOCOL,
|
||||
DivaStateIfcConfig_NT_MODE,
|
||||
DivaStateIfcConfig_POINTTOPOINT,
|
||||
DivaStateIfcConfig_INTERFACENR,
|
||||
DivaStateIfcConfig_BOARDREVISION,
|
||||
DivaStateIfcConfig_SUBFUNCTION,
|
||||
DivaStateIfcConfig_SUBDEVICE,
|
||||
DivaStateIfcConfig_PROTOCOLBUILD,
|
||||
DivaStateIfcConfig_DSPCODEBUILD,
|
||||
DivaStateIfcConfig_ANALOGCHANNELS,
|
||||
DivaStateIfcConfig_PRI,
|
||||
DivaStateIfcConfig_PCIDMA,
|
||||
DivaStateIfcConfig_ADAPTERTYPE,
|
||||
DivaStateIfcConfig_LAW,
|
||||
DivaStateIfcConfig_Max
|
||||
} diva_state_ifc_config_parameters_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010-2011
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Implements to access Diva streaming
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
#include "diva_streaming_vector.h"
|
||||
#include "diva_streaming_manager.h"
|
||||
#include "chan_capi_divastreaming_utils.h"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int diva_streaming_disabled;
|
||||
AST_MUTEX_DEFINE_STATIC(stream_write_lock);
|
||||
|
||||
static diva_entity_queue_t diva_streaming_new; /* protected by stream_write_lock, new streams */
|
||||
|
||||
int capi_DivaStreamingSupported (unsigned controller)
|
||||
{
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
int waitcount = 50;
|
||||
unsigned char manbuf[CAPI_MANUFACTURER_LEN];
|
||||
_cmsg CMSG;
|
||||
int ret = 0;
|
||||
|
||||
if (capi20_get_manufacturer(controller, manbuf) == NULL) {
|
||||
goto done;
|
||||
}
|
||||
if ((strstr((char *)manbuf, "Eicon") == 0) &&
|
||||
(strstr((char *)manbuf, "Dialogic") == 0)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
error = capi_sendf (NULL, 0, CAPI_MANUFACTURER_REQ, controller, get_capi_MessageNumber(),
|
||||
"dw(bs)", _DI_MANU_ID, _DI_STREAM_CTRL, 2, "");
|
||||
|
||||
if (error)
|
||||
goto done;
|
||||
|
||||
while (waitcount) {
|
||||
error = capidev_check_wait_get_cmsg(&CMSG);
|
||||
|
||||
if (IS_MANUFACTURER_CONF(&CMSG) && (CMSG.ManuID == _DI_MANU_ID) &&
|
||||
((CMSG.Class & 0xffff) == _DI_STREAM_CTRL)) {
|
||||
error = (MESSAGE_EXCHANGE_ERROR)(CMSG.Class >> 16);
|
||||
ret = (error == 0);
|
||||
break;
|
||||
}
|
||||
usleep(30000);
|
||||
waitcount--;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int divaStreamingMessageRx (void* user_context, dword message, dword length, const struct _diva_streaming_vector* v, dword nr_v)
|
||||
{
|
||||
diva_stream_scheduling_entry_t* pE = (diva_stream_scheduling_entry_t*)user_context;
|
||||
dword message_type = (message & 0xff);
|
||||
|
||||
if (message_type == 0) { /* IDI message */
|
||||
dword offset = 0;
|
||||
diva_streaming_vector_t vind[8];
|
||||
byte Ind = 0;
|
||||
int vind_nr = 0;
|
||||
int process_indication;
|
||||
|
||||
do {
|
||||
vind_nr = sizeof(vind)/sizeof(vind[0]);
|
||||
offset = diva_streaming_get_indication_data (offset, message, length, v, nr_v, &Ind, vind, &vind_nr);
|
||||
|
||||
process_indication = (diva_streaming_idi_supported_ind (Ind, vind_nr != 0, vind_nr != 0 ? (byte*)vind->data : (byte*)"") != 0);
|
||||
|
||||
if (likely(process_indication != 0)) {
|
||||
if (likely(Ind == 8)) {
|
||||
if (likely(pE->i != 0 && pE->i->NCCI != 0)) {
|
||||
if (pE->i->virtualBridgePeer != 0) {
|
||||
if (pE->i->bridgePeer != 0) {
|
||||
struct capi_pvt* bridgePeer = pE->i->bridgePeer;
|
||||
if (bridgePeer->NCCI != 0 && bridgePeer->diva_stream_entry != 0 &&
|
||||
bridgePeer->diva_stream_entry->diva_stream_state == DivaStreamActive &&
|
||||
bridgePeer->diva_stream_entry->diva_stream->get_tx_in_use (bridgePeer->diva_stream_entry->diva_stream) < 512 &&
|
||||
bridgePeer->diva_stream_entry->diva_stream->get_tx_free (bridgePeer->diva_stream_entry->diva_stream) >
|
||||
2*CAPI_MAX_B3_BLOCK_SIZE+128) {
|
||||
dword i = 0, k = 0, b3len;
|
||||
byte b3buf[CAPI_MAX_B3_BLOCK_SIZE];
|
||||
b3len = diva_streaming_read_vector_data(vind, vind_nr, &i, &k, b3buf, CAPI_MAX_B3_BLOCK_SIZE);
|
||||
bridgePeer->diva_stream_entry->diva_stream->write (bridgePeer->diva_stream_entry->diva_stream,
|
||||
8U << 8 | DIVA_STREAM_MESSAGE_TX_IDI_REQUEST,
|
||||
b3buf, b3len);
|
||||
bridgePeer->diva_stream_entry->diva_stream->flush_stream(bridgePeer->diva_stream_entry->diva_stream);
|
||||
} else {
|
||||
if (bridgePeer->NCCI != 0 && bridgePeer->diva_stream_entry != 0 &&
|
||||
bridgePeer->diva_stream_entry->diva_stream_state == DivaStreamActive) {
|
||||
DBG_ERR(("%s PLCI %04x discarded bridge packet free: %u in use: %u",
|
||||
pE->i->name, pE->i->PLCI & 0xffffU,
|
||||
bridgePeer->diva_stream_entry->diva_stream->get_tx_free (bridgePeer->diva_stream_entry->diva_stream),
|
||||
bridgePeer->diva_stream_entry->diva_stream->get_tx_in_use (bridgePeer->diva_stream_entry->diva_stream)))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
capidev_handle_data_b3_indication_vector (pE->i, vind, vind_nr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dword i = 0, k = 0;
|
||||
word data_length;
|
||||
byte ind_data_buffer[2048+512];
|
||||
data_length = (word)diva_streaming_read_vector_data (vind, vind_nr, &i, &k, ind_data_buffer, sizeof(ind_data_buffer));
|
||||
|
||||
DBG_TRC(("Ind: %02x length:%u", Ind, data_length))
|
||||
}
|
||||
}
|
||||
} while (offset != 0);
|
||||
} else if (message_type == 0xff) { /* System message */
|
||||
switch ((byte)(message >> 8)) {
|
||||
case DIVA_STREAM_MESSAGE_INIT: /* Stream active */
|
||||
if (pE->PLCI == 0 && pE->i != 0) {
|
||||
pE->PLCI = pE->i->PLCI;
|
||||
}
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream active (PLCI=%#x)\n", pE->vname, pE->PLCI);
|
||||
if (pE->diva_stream_state == DivaStreamCreated) {
|
||||
pE->diva_stream_state = DivaStreamActive;
|
||||
} else if (pE->diva_stream_state == DivaStreamCancelSent) {
|
||||
pE->diva_stream->release_stream(pE->diva_stream);
|
||||
pE->i = 0;
|
||||
pE->diva_stream_state = DivaStreamDisconnectSent;
|
||||
}
|
||||
break;
|
||||
|
||||
case DIVA_STREAM_MESSAGE_RX_TX_ACK: /* Resolved Tx flow control */
|
||||
/* cc_verbose(4, 1, "%s: stream tx ack (PLCI=%#x)\n", pE->vname, pE->PLCI); */
|
||||
break;
|
||||
|
||||
case DIVA_STREAM_MESSAGE_SYNC_ACK: /* Sync ack request acknowledge */
|
||||
cc_verbose(4, 1, "%s: stream sync ack (PLCI=%#x, sequence=%08x)\n", pE->vname, pE->PLCI, length);
|
||||
break;
|
||||
|
||||
case DIVA_STREAM_MESSAGE_RELEASE_ACK: /* Release stream acknowledge */
|
||||
pE->diva_stream_state = DivaStreamDisconnected;
|
||||
pE->diva_stream = 0;
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream released (PLCI=%#x)\n", pE->vname, pE->PLCI);
|
||||
break;
|
||||
|
||||
case DIVA_STREAM_MESSAGE_INIT_ERROR: /* Failed to initialize stream */
|
||||
pE->diva_stream_state = DivaStreamDisconnected;
|
||||
pE->diva_stream = 0;
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream init error (PLCI=%#x, error=%d)\n", pE->vname, pE->PLCI, length);
|
||||
break;
|
||||
|
||||
default:
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream unknown system message (PLCI=%#x, message=%08x)\n", pE->vname, pE->PLCI, message);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: unknown stream message (PLCI=%#x, message=%08x)\n", pE->vname, pE->PLCI, message);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create Diva stream
|
||||
*
|
||||
*/
|
||||
void capi_DivaStreamingOn(struct capi_pvt *i, byte streamCommand, _cword messageNumber)
|
||||
{
|
||||
diva_stream_scheduling_entry_t* pE;
|
||||
int ret;
|
||||
char trace_ident[8];
|
||||
unsigned int effectivePLCI;
|
||||
|
||||
if (diva_streaming_disabled)
|
||||
return;
|
||||
|
||||
pE = ast_malloc (sizeof(*pE));
|
||||
if (pE == 0)
|
||||
return;
|
||||
|
||||
snprintf (trace_ident, sizeof(trace_ident), "C%02x", (byte)i->PLCI);
|
||||
trace_ident[sizeof(trace_ident)-1] = 0;
|
||||
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
|
||||
ret = diva_stream_create (&pE->diva_stream, NULL, 255, divaStreamingMessageRx, pE, trace_ident);
|
||||
|
||||
if (ret == 0) {
|
||||
static byte addie[] = { 0x2d /* UID */, 0x01, 0x00, 0x04 /* BC */, 0x04, 0x0, 0x0, 0x0, 0x00 /* 0x20 DMA polling */, 0 /* END */};
|
||||
byte* description = (byte*)pE->diva_stream->description (pE->diva_stream, addie, (byte)sizeof(addie));
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
description[1] = streamCommand;
|
||||
|
||||
description[3] |= 0x01;
|
||||
|
||||
if (streamCommand == 0) {
|
||||
messageNumber = get_capi_MessageNumber();
|
||||
effectivePLCI = i->PLCI;
|
||||
} else {
|
||||
/*
|
||||
PLCI still not assigned. Send to controller and tag with message number
|
||||
where command receives effective
|
||||
*/
|
||||
effectivePLCI = i->controller;
|
||||
}
|
||||
|
||||
error = capi_sendf (NULL, 0, CAPI_MANUFACTURER_REQ, effectivePLCI, messageNumber,
|
||||
"dws", _DI_MANU_ID, _DI_STREAM_CTRL, description);
|
||||
if (error == 0) {
|
||||
pE->diva_stream_state = DivaStreamCreated;
|
||||
pE->PLCI = i->PLCI;
|
||||
pE->i = i;
|
||||
i->diva_stream_entry = pE;
|
||||
memcpy (pE->vname, i->vname, MIN(sizeof(pE->vname), sizeof(i->vname)));
|
||||
pE->vname[sizeof(pE->vname)-1] = 0;
|
||||
pE->rx_flow_control = 0;
|
||||
pE->tx_flow_control = 0;
|
||||
diva_q_add_tail (&diva_streaming_new, &pE->link);
|
||||
} else {
|
||||
pE->diva_stream->release (pE->diva_stream);
|
||||
ast_free (pE);
|
||||
}
|
||||
}
|
||||
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove stream info
|
||||
*
|
||||
* To remove stream from one active connection:
|
||||
* remove stream info
|
||||
* disconnect B3
|
||||
* remove stream
|
||||
* select_b
|
||||
*/
|
||||
void capi_DivaStreamingRemoveInfo(struct capi_pvt *i)
|
||||
{
|
||||
byte description[] = { 2, 0, 0 };
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
int send;
|
||||
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
send = i->diva_stream_entry != 0;
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
|
||||
if (send != 0)
|
||||
error = capi_sendf (NULL, 0, CAPI_MANUFACTURER_REQ, i->PLCI, get_capi_MessageNumber(),
|
||||
"dws", _DI_MANU_ID, _DI_STREAM_CTRL, description);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Send empty stream to inform no Diva streaming is used for this PLCI
|
||||
*/
|
||||
void capi_DivaStreamingStreamNotUsed(struct capi_pvt *i, byte streamCommand, _cword messageNumber)
|
||||
{
|
||||
byte description[] = { 0x04, 0x00, 0x02, 0x00, 0x00 };
|
||||
unsigned int effectivePLCI;
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
description[1] = streamCommand;
|
||||
|
||||
if (streamCommand == 0) {
|
||||
messageNumber = get_capi_MessageNumber();
|
||||
effectivePLCI = i->PLCI;
|
||||
} else {
|
||||
/*
|
||||
PLCI still not assigned. Send to controller and tag with message number
|
||||
where command receives effective
|
||||
*/
|
||||
effectivePLCI = i->controller;
|
||||
}
|
||||
|
||||
error = capi_sendf (NULL, 0, CAPI_MANUFACTURER_REQ, effectivePLCI, messageNumber,
|
||||
"dws", _DI_MANU_ID, _DI_STREAM_CTRL, description);
|
||||
}
|
||||
|
||||
void capi_DivaStreamingRemove(struct capi_pvt *i)
|
||||
{
|
||||
diva_stream_scheduling_entry_t* pE = i->diva_stream_entry;
|
||||
int send_cancel = 0;
|
||||
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
pE = i->diva_stream_entry;
|
||||
if (pE != 0) {
|
||||
i->diva_stream_entry = 0;
|
||||
pE->i = 0;
|
||||
if (pE->diva_stream_state == DivaStreamCreated) {
|
||||
|
||||
if (i->NCCI != 0) {
|
||||
/*
|
||||
If NCCI is not sen then this is no possibility to send cancel request
|
||||
to queued in the IDI L2 streaming info. But in user mode this is OK,
|
||||
if removing PLCI CAPI removes networking entity and this operation
|
||||
causes cancellation of create streaming request.
|
||||
Timeout is only for the rare case where create streaming request was newer
|
||||
sent to hardware.
|
||||
*/
|
||||
send_cancel = 1;
|
||||
}
|
||||
pE->diva_stream_state = DivaStreamCancelSent;
|
||||
pE->cancel_start = time(NULL) + 5;
|
||||
DBG_LOG(("stream cancelled [%p]", pE->diva_stream))
|
||||
} else if (pE->diva_stream_state == DivaStreamActive) {
|
||||
pE->diva_stream->release_stream(pE->diva_stream);
|
||||
pE->diva_stream_state = DivaStreamDisconnectSent;
|
||||
}
|
||||
}
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
|
||||
if (send_cancel != 0) {
|
||||
static byte data[] = { 0x8 /* CONTROL */, 0x01 /* CANCEL */};
|
||||
MESSAGE_EXCHANGE_ERROR error;
|
||||
|
||||
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||
"dwww", data, sizeof(data), 0, 1U << 4);
|
||||
if (likely(error == 0)) {
|
||||
cc_mutex_lock(&i->lock);
|
||||
i->B3count++;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This is only one used to access streaming scheduling list routine.
|
||||
This ensures list can be accessed w/o anly locks
|
||||
|
||||
To ensure exclusive access scheduling queue is static function variable
|
||||
*/
|
||||
void divaStreamingWakeup (void)
|
||||
{
|
||||
static diva_entity_queue_t active_streams;
|
||||
diva_entity_link_t* link;
|
||||
time_t current_time = time (NULL);
|
||||
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
while ((link = diva_q_get_head (&diva_streaming_new)) != 0) {
|
||||
diva_stream_scheduling_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_stream_scheduling_entry_t, link);
|
||||
diva_q_remove (&diva_streaming_new, &pE->link);
|
||||
diva_q_add_tail (&active_streams, &pE->link);
|
||||
}
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
|
||||
for (link = diva_q_get_head (&active_streams); likely(link != 0);) {
|
||||
diva_entity_link_t* next = diva_q_get_next(link);
|
||||
diva_stream_scheduling_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_stream_scheduling_entry_t, link);
|
||||
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
pE->diva_stream->wakeup (pE->diva_stream);
|
||||
if (unlikely(pE->diva_stream_state == DivaStreamCancelSent && pE->cancel_start < current_time)) {
|
||||
DBG_LOG(("stream reclaimed [%p]", pE->diva_stream))
|
||||
pE->diva_stream->release (pE->diva_stream);
|
||||
pE->diva_stream_state = DivaStreamDisconnected;
|
||||
pE->diva_stream = 0;
|
||||
}
|
||||
|
||||
if (unlikely(pE->diva_stream == 0)) {
|
||||
diva_q_remove (&active_streams, &pE->link);
|
||||
if (pE->i != 0) {
|
||||
pE->i->diva_stream_entry = 0;
|
||||
}
|
||||
ast_free (pE);
|
||||
}
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
|
||||
link = next;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int capi_DivaStreamingGetStreamInUse(const struct capi_pvt* i)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
|
||||
capi_DivaStreamLock();
|
||||
if ((i != NULL) && (i->diva_stream_entry != NULL) &&
|
||||
(i->diva_stream_entry->diva_stream_state == DivaStreamActive) &&
|
||||
(i->diva_stream_entry->diva_stream != NULL)) {
|
||||
ret = i->diva_stream_entry->diva_stream->get_tx_in_use (i->diva_stream_entry->diva_stream);
|
||||
}
|
||||
capi_DivaStreamUnLock();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void capi_DivaStreamLock(void)
|
||||
{
|
||||
cc_mutex_lock(&stream_write_lock);
|
||||
}
|
||||
|
||||
void capi_DivaStreamUnLock(void)
|
||||
{
|
||||
cc_mutex_unlock(&stream_write_lock);
|
||||
}
|
||||
|
||||
void capi_DivaStreamingDisable (void) {
|
||||
diva_streaming_disabled = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef __DIVA_CAPI_STREAMING_UTILS_H__
|
||||
#define __DIVA_CAPI_STREAMING_UTILS_H__
|
||||
|
||||
extern int capi_DivaStreamingSupported(unsigned controller);
|
||||
extern void capi_DivaStreamingOn(struct capi_pvt *i, unsigned char streamCommand, _cword messageNumber);
|
||||
extern void capi_DivaStreamingStreamNotUsed(struct capi_pvt *i, byte streamCommand, _cword messageNumber);
|
||||
extern void capi_DivaStreamingRemoveInfo(struct capi_pvt *i);
|
||||
extern void capi_DivaStreamingRemove(struct capi_pvt *i);
|
||||
extern void divaStreamingWakeup(void);
|
||||
extern unsigned int capi_DivaStreamingGetStreamInUse(const struct capi_pvt* i);
|
||||
extern void capi_DivaStreamLock(void);
|
||||
extern void capi_DivaStreamUnLock (void);
|
||||
extern void capi_DivaStreamingDisable (void);
|
||||
|
||||
typedef enum _diva_stream_state {
|
||||
DivaStreamCreated = 0,
|
||||
DivaStreamActive = 1,
|
||||
DivaStreamCancelSent = 2,
|
||||
DivaStreamDisconnectSent = 3,
|
||||
DivaStreamDisconnected = 4
|
||||
} diva_stream_state_t;
|
||||
|
||||
typedef struct _diva_stream_scheduling_entry {
|
||||
diva_entity_link_t link;
|
||||
struct _diva_stream *diva_stream;
|
||||
diva_stream_state_t diva_stream_state;
|
||||
struct capi_pvt *i;
|
||||
int rx_flow_control;
|
||||
int tx_flow_control;
|
||||
char vname[CAPI_MAX_STRING]; /* Cached from capi_pvt */
|
||||
dword PLCI; /* Cached from capi_pvt */
|
||||
time_t cancel_start;
|
||||
} diva_stream_scheduling_entry_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_DEBUGLIB_H__
|
||||
#define __DIVA_STREAMING_DEBUGLIB_H__
|
||||
|
||||
void diva_runtime_error_message (const char* fmt, ...);
|
||||
void diva_runtime_log_message (const char* fmt, ...);
|
||||
void diva_runtime_trace_message (const char* fmt, ...);
|
||||
void diva_runtime_binary_message (const void* data, unsigned long length);
|
||||
|
||||
#define DBG_ERR(__x__) do { diva_runtime_error_message __x__; } while (0);
|
||||
#define DBG_LOG(__x__) do { diva_runtime_log_message __x__; } while (0);
|
||||
#define DBG_TRC(__x__) do { diva_runtime_trace_message __x__; } while (0);
|
||||
#define DBG_BLK(__x__) do { diva_runtime_binary_message __x__; } while (0);
|
||||
|
||||
#define dbg_init(__a__, __b__, __c__) do { static int initialized; if (initialized == 0) { initialized = 1; diva_runtime_log_message("%s %s %u", __a__, __b__, __c__); } } while (0)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_SEGMENT_ALLOC_H__
|
||||
#define __DIVA_SEGMENT_ALLOC_H__
|
||||
|
||||
struct _diva_segment_alloc;
|
||||
struct _diva_segment_alloc_access;
|
||||
|
||||
typedef struct _diva_segment_alloc_access {
|
||||
void (*release)(struct _diva_segment_alloc** ifc);
|
||||
void* (*segment_alloc)(struct _diva_segment_alloc* ifc, dword* lo, dword* hi);
|
||||
void (*segment_free)(struct _diva_segment_alloc* ifc, void* addr, dword lo, dword hi);
|
||||
dword (*get_segment_length)(struct _diva_segment_alloc* ifc);
|
||||
void* (*map_address)(struct _diva_segment_alloc* ifc, dword lo, dword hi, int map_host);
|
||||
void* (*umap_address)(struct _diva_segment_alloc* ifc, dword lo, dword hi, void* local);
|
||||
int (*write_address)(struct _diva_segment_alloc* ifc, dword lo, dword hi, dword data);
|
||||
void (*resource_removed)(struct _diva_segment_alloc* ifc);
|
||||
} diva_segment_alloc_access_t;
|
||||
|
||||
int diva_create_segment_alloc (void* os_context, struct _diva_segment_alloc** segment_alloc);
|
||||
int diva_destroy_segment_alloc (struct _diva_segment_alloc** segment_alloc);
|
||||
diva_segment_alloc_access_t* diva_get_segment_alloc_ifc (struct _diva_segment_alloc* segment_alloc);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_IDI_HOST_IFC__
|
||||
#define __DIVA_STREAMING_IDI_HOST_IFC__
|
||||
|
||||
/*
|
||||
Write data from host to remote side
|
||||
*/
|
||||
struct _diva_stream;
|
||||
struct _diva_segment_alloc_ifc;
|
||||
struct _diva_streaming_idi_host_ifc_w;
|
||||
struct _diva_streaming_idi_host_ifc_w_access;
|
||||
struct _diva_streaming_idi_host_ifc_r;
|
||||
struct _diva_streaming_idi_host_ifc_r_access;
|
||||
|
||||
|
||||
typedef struct _diva_streaming_idi_host_ifc_w_access {
|
||||
int (*release)(struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
diva_streaming_idi_result_t (*release_stream)(struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
int (*write_message)(struct _diva_streaming_idi_host_ifc_w* ifc,
|
||||
dword info, const void* data, dword data_length);
|
||||
int (*ack)(struct _diva_streaming_idi_host_ifc_w* ifc, dword length);
|
||||
int (*ack_rx)(struct _diva_streaming_idi_host_ifc_w* ifc, dword length, int flush_ack);
|
||||
int (*write)(struct _diva_streaming_idi_host_ifc_w* ifc, const void* data, dword data_length);
|
||||
int (*write_indirect)(struct _diva_streaming_idi_host_ifc_w* ifc, dword lo, dword hi, dword length);
|
||||
int (*update_remote)(struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
dword (*get_in_use)(const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
dword (*get_free)(const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
dword (*get_length)(const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
byte (*description)(struct _diva_streaming_idi_host_ifc_w* ifc, byte* dst, byte max_length);
|
||||
int (*init)(struct _diva_streaming_idi_host_ifc_w* ifc, dword version, dword counter, dword info);
|
||||
diva_streaming_idi_result_t (*sync)(struct _diva_streaming_idi_host_ifc_w* ifc, dword ident);
|
||||
diva_streaming_idi_result_t (*trace_ident)(struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
} diva_streaming_idi_host_ifc_w_access_t;
|
||||
|
||||
int diva_streaming_idi_host_ifc_create (struct _diva_streaming_idi_host_ifc_w** ifc,
|
||||
dword number_segments,
|
||||
struct _diva_segment_alloc* segment_alloc,
|
||||
const char* trace_ident);
|
||||
struct _diva_streaming_idi_host_ifc_w_access* diva_streaming_idi_host_ifc_get_access (
|
||||
struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
|
||||
typedef struct _diva_streaming_idi_host_ifc_r_access {
|
||||
int (*release)(struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
int (*wakeup)(struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
byte (*description)(struct _diva_streaming_idi_host_ifc_r* ifc, byte* dst, byte max_length);
|
||||
} diva_streaming_idi_host_ifc_r_access_t;
|
||||
|
||||
int diva_streaming_idi_host_rx_ifc_create (struct _diva_streaming_idi_host_ifc_r** ifc,
|
||||
dword number_segments,
|
||||
struct _diva_segment_alloc* segment_alloc,
|
||||
struct _diva_streaming_idi_host_ifc_w* tx,
|
||||
struct _diva_streaming_idi_host_ifc_w_access* tx_ifc,
|
||||
diva_streaming_idi_rx_notify_user_proc_t notify_user_proc,
|
||||
void* user_context,
|
||||
struct _diva_stream* diva_streaming_manager_ifc,
|
||||
const char* trace_ident);
|
||||
struct _diva_streaming_idi_host_ifc_r_access* diva_streaming_idi_host_rx_ifc_get_access (
|
||||
struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,441 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* vim:ts=2:
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "pc.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_streaming_vector.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
#include "diva_streaming_manager.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_segment_alloc_ifc.h"
|
||||
#include "diva_streaming_idi_host_ifc.h"
|
||||
#include "diva_streaming_idi_host_ifc_impl.h"
|
||||
#include "spi_descriptor.h"
|
||||
|
||||
static int diva_streaming_idi_host_ifc_cleanup (struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static int write_message (struct _diva_streaming_idi_host_ifc_w* ifc,
|
||||
dword info,
|
||||
const void* data,
|
||||
dword data_length);
|
||||
static byte description (diva_streaming_idi_host_ifc_w_t* ifc, byte* dst, byte max_length);
|
||||
static int init (struct _diva_streaming_idi_host_ifc_w* ifc, dword version, dword counter, dword info);
|
||||
static diva_streaming_idi_result_t sync_req (struct _diva_streaming_idi_host_ifc_w* ifc, dword ident);
|
||||
static int ack_data (struct _diva_streaming_idi_host_ifc_w* ifc, dword length);
|
||||
static int ack_rx_data (struct _diva_streaming_idi_host_ifc_w* ifc, dword length, int flush_ack);
|
||||
static int write_data (struct _diva_streaming_idi_host_ifc_w* ifc, const void* data, dword data_length);
|
||||
static int write_indirect (struct _diva_streaming_idi_host_ifc_w* ifc, dword lo, dword hi, dword length);
|
||||
static int update_remote (struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static dword get_in_use (const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static dword get_free (const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static dword get_length (const struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static void write_buffer (diva_streaming_idi_host_ifc_w_t* ifc, const void* data, dword data_length);
|
||||
static void update_write_buffer (diva_streaming_idi_host_ifc_w_t* ifc);
|
||||
static diva_streaming_idi_result_t set_trace_ident (struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
static diva_streaming_idi_result_t release_stream (struct _diva_streaming_idi_host_ifc_w* ifc);
|
||||
|
||||
|
||||
int diva_streaming_idi_host_ifc_create (struct _diva_streaming_idi_host_ifc_w** ifc,
|
||||
dword number_segments,
|
||||
struct _diva_segment_alloc* segment_alloc,
|
||||
const char* trace_ident) {
|
||||
struct _diva_streaming_idi_host_ifc_w* ifc_w = *ifc;
|
||||
diva_segment_alloc_access_t* segment_alloc_access = diva_get_segment_alloc_ifc (segment_alloc);
|
||||
dword i;
|
||||
int free_ifc = 0;
|
||||
|
||||
if (ifc_w == 0) {
|
||||
ifc_w = diva_os_malloc (0, sizeof(*ifc_w));
|
||||
free_ifc = 1;
|
||||
}
|
||||
|
||||
if (ifc_w == 0) {
|
||||
DBG_ERR(("failed to create idi w interface [%s]", trace_ident))
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset (ifc_w, 0x00, sizeof(*ifc_w));
|
||||
memcpy(ifc_w->trace_ident, trace_ident, MIN(strlen(trace_ident), DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH));
|
||||
ifc_w->trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH] = 0;
|
||||
|
||||
ifc_w->nr_segments = MIN(number_segments, DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS);
|
||||
ifc_w->segment_alloc = segment_alloc;
|
||||
ifc_w->free_ifc = free_ifc;
|
||||
|
||||
for (i = 0; i < ifc_w->nr_segments; i++) {
|
||||
ifc_w->segments[i] = (*(segment_alloc_access->segment_alloc))(segment_alloc,
|
||||
&ifc_w->segment_lo[i],
|
||||
&ifc_w->segment_hi[i]);
|
||||
if (ifc_w->segments[i] == 0) {
|
||||
DBG_ERR(("failed to alloc segment [%s]", trace_ident))
|
||||
diva_streaming_idi_host_ifc_cleanup (ifc_w);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
DBG_TRC(("alloc %p %08x:%08x [%s]", ifc_w->segments[i], ifc_w->segment_lo[i], ifc_w->segment_hi[i], trace_ident))
|
||||
|
||||
ifc_w->segment_length[i] = (*(segment_alloc_access->get_segment_length))(segment_alloc);
|
||||
if (i == 0) {
|
||||
*(volatile dword*)(ifc_w->segments[i]+ifc_w->segment_length[i]-sizeof(dword)) = 0;
|
||||
}
|
||||
|
||||
ifc_w->state.length += ifc_w->segment_length[i];
|
||||
}
|
||||
|
||||
ifc_w->ack_rx = 0;
|
||||
|
||||
ifc_w->state.used_length = 0;
|
||||
ifc_w->state.free_length = ifc_w->state.length;
|
||||
|
||||
ifc_w->state.write_buffer = 0;
|
||||
ifc_w->state.write_buffer_position = 0;
|
||||
ifc_w->state.write_buffer_free = ifc_w->segment_length[ifc_w->state.write_buffer];
|
||||
|
||||
ifc_w->state.acknowledge_buffer = 0;
|
||||
ifc_w->state.acknowledge_buffer_position = 0;
|
||||
|
||||
ifc_w->remote.written = 0;
|
||||
|
||||
ifc_w->access.release = diva_streaming_idi_host_ifc_cleanup;
|
||||
ifc_w->access.release_stream = release_stream;
|
||||
ifc_w->access.write_message = write_message;
|
||||
ifc_w->access.ack = ack_data;
|
||||
ifc_w->access.ack_rx = ack_rx_data;
|
||||
ifc_w->access.write = write_data;
|
||||
ifc_w->access.write_indirect = write_indirect;
|
||||
ifc_w->access.update_remote = update_remote;
|
||||
ifc_w->access.get_in_use = get_in_use;
|
||||
ifc_w->access.get_free = get_free;
|
||||
ifc_w->access.get_length = get_length;
|
||||
ifc_w->access.description = description;
|
||||
ifc_w->access.init = init;
|
||||
ifc_w->access.sync = sync_req;
|
||||
ifc_w->access.trace_ident = set_trace_ident;
|
||||
|
||||
*ifc = ifc_w;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct _diva_streaming_idi_host_ifc_w_access* diva_streaming_idi_host_ifc_get_access (
|
||||
struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
return (&ifc->access);
|
||||
}
|
||||
|
||||
static int diva_streaming_idi_host_ifc_cleanup (struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
diva_segment_alloc_access_t* segment_alloc_access = diva_get_segment_alloc_ifc (ifc->segment_alloc);
|
||||
dword i;
|
||||
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
if (ifc->segments[i] != 0) {
|
||||
(*(segment_alloc_access->segment_free))(ifc->segment_alloc,
|
||||
ifc->segments[i],
|
||||
ifc->segment_lo[i],
|
||||
ifc->segment_hi[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ifc->remote_counter_mapped_base != 0) {
|
||||
segment_alloc_access->umap_address (ifc->segment_alloc, ifc->remote_counter_base, 0, ifc->remote_counter_mapped_base);
|
||||
}
|
||||
|
||||
if (ifc->free_ifc != 0) {
|
||||
diva_os_free (0, ifc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void update_write_buffer (diva_streaming_idi_host_ifc_w_t* ifc) {
|
||||
if (ifc->state.write_buffer_free == 0) {
|
||||
ifc->state.write_buffer++;
|
||||
if (ifc->state.write_buffer >= ifc->nr_segments) {
|
||||
ifc->state.write_buffer = 0;
|
||||
}
|
||||
ifc->state.write_buffer_free = ifc->segment_length[ifc->state.write_buffer];
|
||||
ifc->state.write_buffer_position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_buffer (diva_streaming_idi_host_ifc_w_t* ifc, const void* data, dword data_length) {
|
||||
const byte* src = (const byte*)data;
|
||||
dword to_write = data_length;
|
||||
|
||||
while (data_length != 0) {
|
||||
dword to_copy = MIN(ifc->state.write_buffer_free, data_length);
|
||||
memcpy (ifc->segments[ifc->state.write_buffer]+ifc->state.write_buffer_position, src, to_copy);
|
||||
src += to_copy;
|
||||
ifc->state.write_buffer_position += to_copy;
|
||||
ifc->state.write_buffer_free -= to_copy;
|
||||
data_length -= to_copy;
|
||||
update_write_buffer (ifc);
|
||||
}
|
||||
|
||||
ifc->state.free_length -= to_write;
|
||||
ifc->state.used_length += to_write;
|
||||
ifc->remote.written += ((int32)to_write);
|
||||
}
|
||||
|
||||
static void align_write_buffer (diva_streaming_idi_host_ifc_w_t* ifc, dword data_length) {
|
||||
dword to_write = data_length;
|
||||
|
||||
while (data_length != 0) {
|
||||
dword to_copy = MIN(ifc->state.write_buffer_free, data_length);
|
||||
ifc->state.write_buffer_position += to_copy;
|
||||
ifc->state.write_buffer_free -= to_copy;
|
||||
data_length -= to_copy;
|
||||
update_write_buffer (ifc);
|
||||
}
|
||||
|
||||
ifc->state.free_length -= to_write;
|
||||
ifc->state.used_length += to_write;
|
||||
ifc->remote.written += ((int32)to_write);
|
||||
}
|
||||
|
||||
static int write_message (struct _diva_streaming_idi_host_ifc_w* ifc,
|
||||
dword info,
|
||||
const void* data,
|
||||
dword data_length) {
|
||||
dword idi_header_length = ((info & 0xff) == DIVA_STREAM_MESSAGE_TX_IDI_REQUEST && (info & DIVA_STREAMING_IDI_SYSTEM_MESSAGE) == 0) ? (sizeof(diva_spi_msg_hdr_t)+1) : 0;
|
||||
dword length = data_length + idi_header_length + 2 * sizeof(dword); /* data length + message length + info */
|
||||
dword required_length = (length + 31) & ~31;
|
||||
byte tmp[sizeof(dword)+1];
|
||||
byte Req = 0;
|
||||
|
||||
if (required_length > get_free (ifc)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
WRITE_DWORD(tmp, data_length + idi_header_length + sizeof(dword)); /* Write message length without length dword */
|
||||
write_buffer (ifc, tmp, sizeof(dword));
|
||||
|
||||
if ((info & DIVA_STREAMING_IDI_SYSTEM_MESSAGE) == 0) {
|
||||
switch (info & 0xff) {
|
||||
case DIVA_STREAM_MESSAGE_TX_IDI_REQUEST: {
|
||||
dword ack_info = (word)ifc->ack_rx;
|
||||
Req = (byte)(info >> 8);
|
||||
info = DIVA_STREAMING_IDI_TX_REQUEST | (ack_info << 8);
|
||||
ifc->ack_rx -= ack_info;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_DWORD(tmp, info);
|
||||
write_buffer (ifc, tmp, sizeof(dword)); /* Write info */
|
||||
|
||||
if (idi_header_length != 0) {
|
||||
diva_spi_msg_hdr_t* hdr = (diva_spi_msg_hdr_t*)tmp;
|
||||
dword message_length = data_length + idi_header_length;
|
||||
byte* message_data = (byte*)&hdr[1];
|
||||
|
||||
hdr->Id = 0;
|
||||
hdr->Ind = Req;
|
||||
hdr->length_lo = (byte)message_length;
|
||||
hdr->length_hi = (byte)(message_length >> 8);
|
||||
message_data[0] = 0;
|
||||
|
||||
write_buffer (ifc, hdr, idi_header_length);
|
||||
}
|
||||
|
||||
write_buffer (ifc, data, data_length); /* Write data */
|
||||
|
||||
align_write_buffer (ifc, required_length - length); /* Move to next message */
|
||||
|
||||
return (data_length);
|
||||
}
|
||||
|
||||
static int ack_data (struct _diva_streaming_idi_host_ifc_w* ifc, dword length) {
|
||||
if (length > get_in_use (ifc)) {
|
||||
DBG_ERR(("ack error ack:%u in use:%u free:%u [%s]", length, get_in_use (ifc), ifc->state.free_length, ifc->trace_ident))
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ifc->state.free_length += length;
|
||||
ifc->state.used_length -= length;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int ack_rx_data (struct _diva_streaming_idi_host_ifc_w* ifc, dword length, int flush_ack) {
|
||||
flush_ack |= (ifc->ack_rx != 0);
|
||||
|
||||
ifc->ack_rx += length;
|
||||
|
||||
while (flush_ack != 0 && ifc->ack_rx != 0 && get_free (ifc) > 128) {
|
||||
dword info = (word)ifc->ack_rx;
|
||||
|
||||
ifc->ack_rx -= info;
|
||||
info = ((dword)DIVA_STREAMING_IDI_RX_ACK_MSG) | (info << 8) | DIVA_STREAMING_IDI_SYSTEM_MESSAGE;
|
||||
|
||||
write_message (ifc, info, 0, 0);
|
||||
update_remote (ifc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static byte description (diva_streaming_idi_host_ifc_w_t* ifc, byte* dst, byte max_length) {
|
||||
byte length = 0;
|
||||
dword i;
|
||||
|
||||
DBG_TRC(("tx description %u segments [%s]", ifc->nr_segments, ifc->trace_ident))
|
||||
|
||||
dst[length++] = (byte)(ifc->nr_segments);
|
||||
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
DBG_TRC((" tx lo[%u] %08x [%s]", i, ifc->segment_lo[i], ifc->trace_ident))
|
||||
WRITE_DWORD(&dst[length], ifc->segment_lo[i]);
|
||||
length += sizeof(dword);
|
||||
}
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
DBG_TRC((" tx hi[%u] %08x [%s]", i, ifc->segment_hi[i], ifc->trace_ident))
|
||||
WRITE_DWORD(&dst[length], ifc->segment_hi[i]);
|
||||
length += sizeof(dword);
|
||||
}
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
DBG_TRC((" length[%u] %u [%s]", i, ifc->segment_length[i], ifc->trace_ident))
|
||||
WRITE_DWORD(&dst[length], ifc->segment_length[i]);
|
||||
length += sizeof(dword);
|
||||
}
|
||||
|
||||
return (length);
|
||||
}
|
||||
|
||||
static int init (struct _diva_streaming_idi_host_ifc_w* ifc, dword version, dword counter, dword info) {
|
||||
diva_segment_alloc_access_t* segment_alloc_access = diva_get_segment_alloc_ifc (ifc->segment_alloc);
|
||||
|
||||
if ((info & DIVA_STREAMING_MANAGER_TX_COUNTER_IN_TX_PAGE) != 0) {
|
||||
ifc->segment_length[0] -= sizeof(dword);
|
||||
ifc->state.length -= sizeof(dword);
|
||||
ifc->state.write_buffer_free -= sizeof(dword);
|
||||
ifc->state.free_length -= sizeof(dword);
|
||||
ifc->remote_counter_mapped = (dword*)(ifc->segments[0]+ifc->segment_length[0]);
|
||||
ifc->remote_counter_mapped_base = 0;
|
||||
} else {
|
||||
ifc->remote_counter_offset = counter % (4*1024);
|
||||
ifc->remote_counter_base = counter - ifc->remote_counter_offset;
|
||||
|
||||
ifc->remote_counter_mapped_base = segment_alloc_access->map_address (ifc->segment_alloc,
|
||||
ifc->remote_counter_base, 0,
|
||||
(info & DIVA_STREAMING_MANAGER_HOST_USER_MODE_STREAM) != 0);
|
||||
if (ifc->remote_counter_mapped_base != 0) {
|
||||
byte* p = ifc->remote_counter_mapped_base;
|
||||
ifc->remote_counter_mapped = (dword*)&p[ifc->remote_counter_offset];
|
||||
} else {
|
||||
DBG_TRC(("stream uses system call [%s]", ifc->trace_ident))
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t sync_req (struct _diva_streaming_idi_host_ifc_w* ifc, dword ident) {
|
||||
if (get_free (ifc) > 128) {
|
||||
dword data[2];
|
||||
|
||||
DBG_TRC(("sync request %08x [%s]", ident, ifc->trace_ident))
|
||||
|
||||
data[0] = ident;
|
||||
data[1] = 0;
|
||||
|
||||
write_message (ifc, DIVA_STREAMING_IDI_SYNC_REQ|DIVA_STREAMING_IDI_SYSTEM_MESSAGE, data, sizeof(data));
|
||||
update_remote (ifc);
|
||||
|
||||
return (DivaStreamingIdiResultOK);
|
||||
} else {
|
||||
return (DivaStreamingIdiResultBusy);
|
||||
}
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t set_trace_ident (struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
if (get_free (ifc) > 128) {
|
||||
dword data[2];
|
||||
DBG_TRC(("set trace ident [%s]", ifc->trace_ident))
|
||||
|
||||
memcpy (data, ifc->trace_ident, sizeof(data[0]));
|
||||
data[1] = 0;
|
||||
|
||||
write_message (ifc, DIVA_STREAMING_IDI_SET_DEBUG_IDENT|DIVA_STREAMING_IDI_SYSTEM_MESSAGE, data, sizeof(data));
|
||||
update_remote (ifc);
|
||||
|
||||
return (DivaStreamingIdiResultOK);
|
||||
} else {
|
||||
return (DivaStreamingIdiResultBusy);
|
||||
}
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t release_stream (struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
dword data[1];
|
||||
int ret;
|
||||
|
||||
DBG_LOG(("stream release [%s]", ifc->trace_ident))
|
||||
|
||||
data[0] = 0;
|
||||
|
||||
ret = write_message (ifc, DIVA_STREAMING_IDI_RELEASE|DIVA_STREAMING_IDI_SYSTEM_MESSAGE, data, sizeof(data));
|
||||
update_remote (ifc);
|
||||
|
||||
return (ret != 0 ? DivaStreamingIdiResultOK : DivaStreamingIdiResultBusy);
|
||||
}
|
||||
|
||||
static int write_data (struct _diva_streaming_idi_host_ifc_w* ifc, const void* data, dword data_length) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int write_indirect (struct _diva_streaming_idi_host_ifc_w* ifc, dword lo, dword hi, dword length) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int update_remote (struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
int ret = 0;
|
||||
|
||||
if (ifc->remote_counter_mapped != 0) {
|
||||
ifc->remote_counter_mapped[0] = ifc->remote.written;
|
||||
} else {
|
||||
diva_segment_alloc_access_t* segment_alloc_access = diva_get_segment_alloc_ifc (ifc->segment_alloc);
|
||||
|
||||
ret = segment_alloc_access->write_address (ifc->segment_alloc,
|
||||
ifc->remote_counter_base + ifc->remote_counter_offset,
|
||||
0,
|
||||
ifc->remote.written);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static dword get_in_use (const struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
return (ifc->state.used_length);
|
||||
}
|
||||
|
||||
static dword get_free (const struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
return (ifc->state.free_length);
|
||||
}
|
||||
|
||||
static dword get_length (const struct _diva_streaming_idi_host_ifc_w* ifc) {
|
||||
return (ifc->state.length);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_IDI_HOST_IFC_IMPL_H__
|
||||
#define __DIVA_STREAMING_IDI_HOST_IFC_IMPL_H__
|
||||
|
||||
struct _diva_segment_alloc_ifc;
|
||||
struct _diva_streaming_idi_host_ifc_w_access;
|
||||
struct _diva_streaming_idi_host_ifc_w;
|
||||
|
||||
#define DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS 8
|
||||
typedef struct _diva_streaming_idi_host_ifc_w {
|
||||
struct _diva_streaming_idi_host_ifc_w_access access;
|
||||
|
||||
byte* segments[DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS]; /**< buffer segments */
|
||||
dword segment_length[DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS]; /**< length of every segment */
|
||||
dword segment_lo[DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS];
|
||||
dword segment_hi[DIVA_STREAMING_IDI_HOST_IFC_MAX_SEGMENTS];
|
||||
dword nr_segments; /**< number of available segments */
|
||||
|
||||
struct _diva_segment_alloc* segment_alloc;
|
||||
|
||||
struct {
|
||||
dword length; /**< overall length including all segments */
|
||||
dword used_length; /**< overall written and not acknowledged */
|
||||
dword free_length; /**< overall length available */
|
||||
|
||||
dword write_buffer; /**< current write segment buffer */
|
||||
dword write_buffer_position; /**< position in write segment */
|
||||
dword write_buffer_free; /**< free space in write segment */
|
||||
|
||||
dword acknowledge_buffer; /**< acknowledge segment */
|
||||
dword acknowledge_buffer_position; /**< position in acknowledge segment */
|
||||
dword acknowledge_buffer_free;
|
||||
} state;
|
||||
|
||||
struct {
|
||||
int32 written; /**< incremented every time data written by amount of data written in the buffer and
|
||||
written to opposite side */
|
||||
} remote;
|
||||
|
||||
dword remote_counter_base; /* Remote counter page BUS address */
|
||||
dword remote_counter_offset; /* Remote counter offset from page start */
|
||||
void* remote_counter_mapped_base; /* Remote counter page BUS address mapped */
|
||||
volatile dword* remote_counter_mapped; /* Remote counter mapped */
|
||||
|
||||
dword ack_rx;
|
||||
|
||||
int free_ifc;
|
||||
|
||||
char trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH+1];
|
||||
} diva_streaming_idi_host_ifc_w_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* vim:ts=2:
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "pc.h"
|
||||
#include "diva_streaming_vector.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_streaming_manager.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_segment_alloc_ifc.h"
|
||||
#include "diva_streaming_idi_host_ifc.h"
|
||||
#include "diva_streaming_idi_host_rx_ifc_impl.h"
|
||||
|
||||
/*
|
||||
* LOCALS
|
||||
*/
|
||||
static void update_buffer (struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
static void align_buffer (struct _diva_streaming_idi_host_ifc_r* ifc, dword length, diva_streaming_vector_t* v, dword* nr_v);
|
||||
static int diva_streaming_idi_host_rx_data (struct _diva_streaming_idi_host_ifc_r* ifc, dword length);
|
||||
static dword copy_message_data (byte* dst, const diva_streaming_vector_t* v, dword nr_v);
|
||||
static int diva_streaming_idi_host_rx_process_message (struct _diva_streaming_idi_host_ifc_r* ifc,
|
||||
dword message,
|
||||
dword data_length,
|
||||
const diva_streaming_vector_t* v, dword nr_v);
|
||||
static byte description (diva_streaming_idi_host_ifc_r_t* ifc, byte* dst, byte max_length);
|
||||
static int diva_streaming_idi_host_rx_ifc_rx (struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
static int diva_streaming_idi_host_rx_ifc_cleanup (struct _diva_streaming_idi_host_ifc_r* ifc);
|
||||
|
||||
int diva_streaming_idi_host_rx_ifc_create (struct _diva_streaming_idi_host_ifc_r** ifc,
|
||||
dword number_segments,
|
||||
struct _diva_segment_alloc* segment_alloc,
|
||||
struct _diva_streaming_idi_host_ifc_w* tx,
|
||||
struct _diva_streaming_idi_host_ifc_w_access* tx_ifc,
|
||||
diva_streaming_idi_rx_notify_user_proc_t notify_user_proc,
|
||||
void* user_context,
|
||||
struct _diva_stream* diva_streaming_manager_ifc,
|
||||
const char* trace_ident) {
|
||||
struct _diva_streaming_idi_host_ifc_r* ifc_r = *ifc;
|
||||
diva_segment_alloc_access_t* segment_access = diva_get_segment_alloc_ifc (segment_alloc);
|
||||
dword i;
|
||||
int free_ifc = 0;
|
||||
|
||||
if (ifc_r == 0) {
|
||||
ifc_r = diva_os_malloc (0, sizeof(*ifc_r));
|
||||
free_ifc = 1;
|
||||
}
|
||||
|
||||
if (ifc_r == 0) {
|
||||
DBG_ERR(("failed to create idi r interface [%s]", trace_ident))
|
||||
return (-1);
|
||||
}
|
||||
|
||||
memset (ifc_r, 0x00, sizeof(*ifc_r));
|
||||
memcpy(ifc_r->trace_ident, trace_ident, MIN(strlen(trace_ident), DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH));
|
||||
ifc_r->trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH] = 0;
|
||||
|
||||
ifc_r->nr_segments = MIN(number_segments, DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS);
|
||||
ifc_r->segment_alloc = segment_alloc;
|
||||
ifc_r->free_ifc = free_ifc;
|
||||
ifc_r->diva_streaming_manager_ifc = diva_streaming_manager_ifc;
|
||||
|
||||
for (i = 0; i < ifc_r->nr_segments; i++) {
|
||||
ifc_r->segments[i] = (*(segment_access->segment_alloc))(segment_alloc,
|
||||
&ifc_r->segment_lo[i],
|
||||
&ifc_r->segment_hi[i]);
|
||||
if (ifc_r->segments[i] == 0) {
|
||||
DBG_ERR(("failed to alloc segment [%s]", trace_ident))
|
||||
diva_streaming_idi_host_rx_ifc_cleanup (ifc_r);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
DBG_TRC(("alloc %p %08x:%08x [%s]", ifc_r->segments[i], ifc_r->segment_lo[i], ifc_r->segment_hi[i], trace_ident))
|
||||
|
||||
ifc_r->segment_length[i] = (*(segment_access->get_segment_length))(segment_alloc);
|
||||
|
||||
if (i == 0) {
|
||||
ifc_r->remote_counter = (int32*)ifc_r->segments[i];
|
||||
ifc_r->segments[i] += sizeof(dword);
|
||||
ifc_r->segment_length[i] -= sizeof(dword);
|
||||
}
|
||||
|
||||
ifc_r->state.length += ifc_r->segment_length[i];
|
||||
}
|
||||
|
||||
ifc_r->remote_counter[0] = 0;
|
||||
|
||||
ifc_r->tx = tx;
|
||||
ifc_r->tx_ifc = tx_ifc;
|
||||
ifc_r->notify_user_proc = notify_user_proc;
|
||||
ifc_r->user_context = user_context;
|
||||
|
||||
ifc_r->current_segment = 0;
|
||||
ifc_r->current_pos = 0;
|
||||
ifc_r->current_free = ifc_r->segment_length[ifc_r->current_segment];
|
||||
|
||||
ifc_r->access.release = diva_streaming_idi_host_rx_ifc_cleanup;
|
||||
ifc_r->access.wakeup = diva_streaming_idi_host_rx_ifc_rx;
|
||||
ifc_r->access.description = description;
|
||||
|
||||
*ifc = ifc_r;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct _diva_streaming_idi_host_ifc_r_access* diva_streaming_idi_host_rx_ifc_get_access (
|
||||
struct _diva_streaming_idi_host_ifc_r* ifc) {
|
||||
return (&ifc->access);
|
||||
}
|
||||
|
||||
static int diva_streaming_idi_host_rx_ifc_cleanup (struct _diva_streaming_idi_host_ifc_r* ifc) {
|
||||
diva_segment_alloc_access_t* segment_access = diva_get_segment_alloc_ifc (ifc->segment_alloc);
|
||||
dword i;
|
||||
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
if (ifc->segments[i] != 0) {
|
||||
(*(segment_access->segment_free))(ifc->segment_alloc,
|
||||
ifc->segments[i] - ((i == 0) ? sizeof(dword) : 0),
|
||||
ifc->segment_lo[i],
|
||||
ifc->segment_hi[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ifc->free_ifc != 0) {
|
||||
diva_os_free (0, ifc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data
|
||||
*/
|
||||
static int diva_streaming_idi_host_rx_ifc_rx (struct _diva_streaming_idi_host_ifc_r* ifc) {
|
||||
int32 local_counter;
|
||||
int32 length;
|
||||
int ret = 0;
|
||||
int msg_count = 0, ack_ret;
|
||||
|
||||
do {
|
||||
local_counter = ifc->remote_counter[0];
|
||||
length = local_counter - ifc->local_counter;
|
||||
|
||||
if (length != 0) {
|
||||
ret += length;
|
||||
ifc->local_counter = local_counter;
|
||||
ack_ret = diva_streaming_idi_host_rx_data (ifc, length);
|
||||
if (ifc->released == DIVA_STREAM_MESSAGE_RELEASE_ACK || ifc->released == DIVA_STREAM_MESSAGE_INIT_ERROR) {
|
||||
if (ifc->notify_user_proc (ifc->user_context, ((dword)ifc->released) << 8 | 0xffU, ifc->released_info, 0, 0) == 0) {
|
||||
ifc->diva_streaming_manager_ifc->release(ifc->diva_streaming_manager_ifc);
|
||||
} else {
|
||||
ifc->released = DIVA_STREAM_MESSAGE_RELEASED;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
ifc->tx_ifc->ack_rx (ifc->tx, length, msg_count != 0 || ack_ret == 0);
|
||||
msg_count++;
|
||||
}
|
||||
} while(length != 0);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void update_buffer (struct _diva_streaming_idi_host_ifc_r* ifc) {
|
||||
if (ifc->current_free == 0) {
|
||||
ifc->current_segment++;
|
||||
if (ifc->current_segment >= ifc->nr_segments) {
|
||||
ifc->current_segment = 0;
|
||||
}
|
||||
ifc->current_free = ifc->segment_length[ifc->current_segment];
|
||||
ifc->current_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void align_buffer (struct _diva_streaming_idi_host_ifc_r* ifc, dword length, diva_streaming_vector_t* v, dword* nr_v) {
|
||||
while (length != 0) {
|
||||
dword to_copy = MIN(ifc->current_free, length);
|
||||
|
||||
if (v != 0) {
|
||||
v[*nr_v].data = ifc->segments[ifc->current_segment] + ifc->current_pos;
|
||||
v[*nr_v].length = to_copy;
|
||||
nr_v[0]++;
|
||||
}
|
||||
|
||||
ifc->current_pos += to_copy;
|
||||
ifc->current_free -= to_copy;
|
||||
length -= to_copy;
|
||||
update_buffer (ifc);
|
||||
}
|
||||
}
|
||||
|
||||
static dword copy_message_data (byte* dst, const diva_streaming_vector_t* v, dword nr_v) {
|
||||
dword i, length;
|
||||
|
||||
for (i = 0, length = 0; i < nr_v; i++) {
|
||||
memcpy (&dst[length], v[i].data, v[i].length);
|
||||
length += v[i].length;
|
||||
}
|
||||
|
||||
return (length);
|
||||
}
|
||||
|
||||
/*
|
||||
Return one if processed DIVA_STREAMING_IDI_TX_ACK_MSG
|
||||
*/
|
||||
static int diva_streaming_idi_host_rx_process_message (struct _diva_streaming_idi_host_ifc_r* ifc,
|
||||
dword message,
|
||||
dword data_length,
|
||||
const diva_streaming_vector_t* v, dword nr_v) {
|
||||
int ret = 0;
|
||||
|
||||
switch (message) {
|
||||
case DIVA_STREAMING_IDI_TX_INIT_MSG: /* Initialization */
|
||||
if (data_length != (DIVA_STREAMING_IDI_TX_INIT_MSG_LENGTH - sizeof(dword) - sizeof(word))) {
|
||||
DBG_ERR(("wrong message length %02x %u [%s]", DIVA_STREAMING_IDI_TX_INIT_MSG, data_length, ifc->trace_ident))
|
||||
return (0);
|
||||
}
|
||||
{
|
||||
dword counter;
|
||||
dword info;
|
||||
byte version;
|
||||
|
||||
copy_message_data (ifc->system_message, v, nr_v);
|
||||
|
||||
version = ifc->system_message[0];
|
||||
counter = READ_DWORD(&ifc->system_message[1]);
|
||||
info = READ_DWORD(&ifc->system_message[5]);
|
||||
|
||||
DBG_TRC(("version:%u counter:%08x info:%08x [%s]", version, counter, info, ifc->trace_ident))
|
||||
|
||||
ifc->tx_ifc->init (ifc->tx, version, counter, info);
|
||||
ifc->tx_ifc->trace_ident (ifc->tx);
|
||||
ifc->notify_user_proc (ifc->user_context, DIVA_STREAM_MESSAGE_INIT << 8 | 0xffU, 0, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case DIVA_STREAMING_IDI_TX_ACK_MSG:
|
||||
if (data_length < (DIVA_STREAMING_IDI_TX_ACK_MSG_LENGTH - sizeof(dword) - sizeof(word))) {
|
||||
DBG_ERR(("wrong message length %02x %u [%s]", DIVA_STREAMING_IDI_TX_ACK_MSG, data_length, ifc->trace_ident))
|
||||
return (0);
|
||||
}
|
||||
copy_message_data (ifc->system_message, v, nr_v);
|
||||
DBG_TRC(("Ind:%02x %u seq:%u [%s]",
|
||||
DIVA_STREAMING_IDI_TX_ACK_MSG,
|
||||
((word)ifc->system_message[0]) | (((word)ifc->system_message[1]) << 8),
|
||||
ifc->system_message[2],
|
||||
ifc->trace_ident))
|
||||
ifc->tx_ifc->ack (ifc->tx, ((word)ifc->system_message[0]) | (((word)ifc->system_message[1]) << 8));
|
||||
ret = 1;
|
||||
ifc->notify_user_proc (ifc->user_context, DIVA_STREAM_MESSAGE_RX_TX_ACK << 8 | 0xffU, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case DIVA_STREAMING_IDI_TX_SYNC_ACK:
|
||||
if (data_length != (DIVA_STREAMING_IDI_TX_SYNC_ACK_LENGTH - sizeof(dword) - sizeof(word))) {
|
||||
DBG_ERR(("wrong message length %02x %u [%s]", DIVA_STREAMING_IDI_TX_SYNC_ACK, data_length, ifc->trace_ident))
|
||||
return (0);
|
||||
}
|
||||
copy_message_data (ifc->system_message, v, nr_v);
|
||||
{
|
||||
dword ident = READ_DWORD(&ifc->system_message[0]);
|
||||
DBG_TRC(("sync ack %08x [%s]", ident, ifc->trace_ident))
|
||||
|
||||
ifc->notify_user_proc (ifc->user_context, DIVA_STREAM_MESSAGE_SYNC_ACK << 8 | 0xffU, ident, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case DIVA_STREAMING_IDI_RELEASE_ACK:
|
||||
if (data_length != (DIVA_STREAMING_IDI_RELEASE_ACK_LENGTH - sizeof(dword) - sizeof(word))) {
|
||||
DBG_ERR(("wrong message length %02x %u [%s]", DIVA_STREAMING_IDI_RELEASE_ACK, data_length, ifc->trace_ident))
|
||||
return (0);
|
||||
}
|
||||
DBG_LOG(("stream release ack [%s]", ifc->trace_ident))
|
||||
ifc->released = DIVA_STREAM_MESSAGE_RELEASE_ACK;
|
||||
ifc->released_info = 0;
|
||||
break;
|
||||
|
||||
case DIVA_STREAMING_IDI_TX_INIT_ERROR:
|
||||
if (data_length < DIVA_STREAMING_IDI_TX_INIT_ERROR_LENGTH - sizeof(dword) - sizeof(word) || data_length >= sizeof(ifc->system_message)) {
|
||||
DBG_ERR(("wrong message length %02x %u [%s]", DIVA_STREAMING_IDI_TX_INIT_ERROR, data_length, ifc->trace_ident))
|
||||
}
|
||||
copy_message_data (ifc->system_message, v, nr_v);
|
||||
{
|
||||
dword error = READ_DWORD(&ifc->system_message[0]);
|
||||
DBG_LOG(("stream init error %08x [%s]", error, ifc->trace_ident))
|
||||
ifc->released = DIVA_STREAM_MESSAGE_INIT_ERROR;
|
||||
ifc->released_info = error;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG_ERR(("unknown message %08x %u [%s]", message, data_length, ifc->trace_ident))
|
||||
break;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
Return one of only one system ack tx message was processed
|
||||
*/
|
||||
static int diva_streaming_idi_host_rx_data (struct _diva_streaming_idi_host_ifc_r* ifc, dword length) {
|
||||
diva_streaming_vector_t v[DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS+2];
|
||||
dword nr_v;
|
||||
int msg_count = 0, ack_msg = 0;
|
||||
|
||||
|
||||
while (length != 0) {
|
||||
dword hdr = *(dword*)(ifc->segments[ifc->current_segment] + ifc->current_pos);
|
||||
dword data_length_lo = hdr & 0xffU;
|
||||
dword data_length_hi = (hdr >> 8) & 0xffU;
|
||||
dword data_length = data_length_lo | (data_length_hi << 8);
|
||||
dword message_length = ((data_length + (sizeof(dword)-1)) & ~(sizeof(dword)-1));
|
||||
dword message_type = (hdr >> 16) & 0xff;
|
||||
dword message = (hdr >> 24) & 0xff;
|
||||
|
||||
length -= (message_length + sizeof(dword)-1) & ~(sizeof(dword)-1);
|
||||
|
||||
nr_v = 0;
|
||||
if (message_type != 0xff && (message & 0x0f) == 0x0f) {
|
||||
/*
|
||||
Tx ack sent as part of IDI N_COMBI_IND message
|
||||
*/
|
||||
byte tmp[sizeof(dword)+sizeof(word)];
|
||||
dword tx_ack;
|
||||
|
||||
align_buffer (ifc, sizeof(dword)+sizeof(word), v, &nr_v); /* Header */
|
||||
copy_message_data (tmp, v, nr_v);
|
||||
tx_ack = ((dword)tmp[4]) | (((dword)tmp[5]) << 8);
|
||||
|
||||
if (tx_ack != 0) {
|
||||
ifc->tx_ifc->ack (ifc->tx, tx_ack);
|
||||
ifc->notify_user_proc (ifc->user_context, DIVA_STREAM_MESSAGE_RX_TX_ACK << 8 | 0xffU, 0, 0, 0);
|
||||
}
|
||||
|
||||
nr_v = 0;
|
||||
} else {
|
||||
align_buffer (ifc, sizeof(dword)+sizeof(word), 0, 0); /* Header */
|
||||
}
|
||||
align_buffer (ifc, data_length - sizeof(dword) - sizeof(word), v, &nr_v);
|
||||
|
||||
if (message_type == 0xff) {
|
||||
ack_msg |= diva_streaming_idi_host_rx_process_message (ifc, message, data_length - sizeof(dword) - sizeof(word), v, nr_v);
|
||||
if (ifc->released != 0)
|
||||
return (1);
|
||||
} else if (nr_v != 0) {
|
||||
ifc->notify_user_proc (ifc->user_context, message << 8, data_length - sizeof(dword) - sizeof(word), v, nr_v);
|
||||
}
|
||||
align_buffer (ifc, message_length - data_length, 0, 0);
|
||||
msg_count++;
|
||||
}
|
||||
|
||||
return (msg_count == 1 && ack_msg != 0);
|
||||
}
|
||||
|
||||
static byte description (diva_streaming_idi_host_ifc_r_t* ifc, byte* dst, byte max_length) {
|
||||
byte length = 0;
|
||||
dword i;
|
||||
|
||||
DBG_TRC(("rx description %u segments [%s]", ifc->nr_segments, ifc->trace_ident))
|
||||
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
DBG_TRC((" rx lo[%u] %08x [%s]", i, ifc->segment_lo[i], ifc->trace_ident))
|
||||
WRITE_DWORD(&dst[length], ifc->segment_lo[i]);
|
||||
length += sizeof(dword);
|
||||
}
|
||||
for (i = 0; i < ifc->nr_segments; i++) {
|
||||
DBG_TRC((" rx hi[%u] %08x [%s]", i, ifc->segment_hi[i], ifc->trace_ident))
|
||||
WRITE_DWORD(&dst[length], ifc->segment_hi[i]);
|
||||
length += sizeof(dword);
|
||||
}
|
||||
|
||||
return (length);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_IDI_HOST_RX_IFC_IMPL_H__
|
||||
#define __DIVA_STREAMING_IDI_HOST_RX_IFC_IMPL_H__
|
||||
|
||||
|
||||
struct _diva_segment_alloc_ifc;
|
||||
struct _diva_streaming_idi_host_ifc_r_access;
|
||||
struct _diva_streaming_idi_host_ifc_r;
|
||||
|
||||
|
||||
#define DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS 8
|
||||
typedef struct _diva_streaming_idi_host_ifc_r {
|
||||
struct _diva_streaming_idi_host_ifc_r_access access;
|
||||
|
||||
byte* segments[DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS]; /**< buffer segments */
|
||||
dword segment_length[DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS]; /**< length of every segment */
|
||||
dword segment_lo[DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS];
|
||||
dword segment_hi[DIVA_STREAMING_IDI_HOST_RX_IFC_MAX_SEGMENTS];
|
||||
dword nr_segments; /**< number of available segments */
|
||||
|
||||
volatile int32* remote_counter; /**< updated by remote side, located at begin of first segment */
|
||||
volatile int32 local_counter;
|
||||
|
||||
dword current_segment;
|
||||
dword current_pos;
|
||||
dword current_free;
|
||||
|
||||
struct _diva_segment_alloc* segment_alloc;
|
||||
|
||||
struct _diva_streaming_idi_host_ifc_w* tx;
|
||||
struct _diva_streaming_idi_host_ifc_w_access* tx_ifc;
|
||||
diva_streaming_idi_rx_notify_user_proc_t notify_user_proc;
|
||||
void* user_context;
|
||||
|
||||
byte system_message[512];
|
||||
|
||||
int free_ifc;
|
||||
|
||||
struct {
|
||||
dword length; /**< overall length including all segments */
|
||||
} state;
|
||||
|
||||
struct _diva_stream* diva_streaming_manager_ifc;
|
||||
dword released;
|
||||
dword released_info;
|
||||
|
||||
char trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH+1];
|
||||
} diva_streaming_idi_host_ifc_r_t;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "pc.h"
|
||||
#include "diva_streaming_result.h"
|
||||
#include "diva_streaming_vector.h"
|
||||
#include "diva_streaming_manager.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
#include "diva_segment_alloc_ifc.h"
|
||||
#include "diva_streaming_idi_host_ifc.h"
|
||||
|
||||
|
||||
typedef struct _diva_stream_manager {
|
||||
diva_stream_t ifc;
|
||||
int user_segment_alloc;
|
||||
struct _diva_segment_alloc* segment_alloc;
|
||||
diva_segment_alloc_access_t* segment_alloc_ifc;
|
||||
struct _diva_streaming_idi_host_ifc_w* tx;
|
||||
struct _diva_streaming_idi_host_ifc_w_access* tx_ifc;
|
||||
struct _diva_streaming_idi_host_ifc_r* rx;
|
||||
struct _diva_streaming_idi_host_ifc_r_access* rx_ifc;
|
||||
diva_streaming_idi_rx_notify_user_proc_t rx_proc;
|
||||
void* rx_proc_context;
|
||||
|
||||
byte description[0xff-32];
|
||||
|
||||
char trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH+1];
|
||||
} diva_stream_manager_t;
|
||||
|
||||
/*
|
||||
* LOCALS
|
||||
*/
|
||||
static int message_input_proc (void* user_context, dword message, dword length, const diva_streaming_vector_t* v, dword nr_v);
|
||||
static diva_streaming_idi_result_t diva_stream_manager_release (struct _diva_stream* ifc);
|
||||
static diva_streaming_idi_result_t diva_stream_manager_release_stream (struct _diva_stream* ifc);
|
||||
static diva_streaming_idi_result_t diva_stream_manager_write (struct _diva_stream* ifc, dword message, const void* data, dword length);
|
||||
static diva_streaming_idi_result_t diva_stream_manager_wakeup (struct _diva_stream* ifc);
|
||||
static const byte* diva_stream_manager_description (struct _diva_stream* ifc, const byte* addie, byte addielen);
|
||||
static diva_streaming_idi_result_t diva_stream_manager_sync_req (struct _diva_stream* ifc, dword ident);
|
||||
static diva_streaming_idi_result_t diva_stream_flush (struct _diva_stream* ifc);
|
||||
static dword diva_stream_get_tx_free (const struct _diva_stream* ifc);
|
||||
static dword diva_stream_get_tx_in_use (const struct _diva_stream* ifc);
|
||||
static void diva_notify_os_resource_removed (struct _diva_stream* ifc);
|
||||
|
||||
diva_streaming_idi_result_t diva_stream_create (struct _diva_stream** ifc,
|
||||
void* os_context,
|
||||
dword length,
|
||||
diva_streaming_idi_rx_notify_user_proc_t rx,
|
||||
void* rx_context,
|
||||
const char* trace_ident) {
|
||||
return (diva_stream_create_with_user_segment_alloc (ifc, os_context, length, rx, rx_context, trace_ident, 0));
|
||||
}
|
||||
|
||||
diva_streaming_idi_result_t diva_stream_create_with_user_segment_alloc (struct _diva_stream** ifc,
|
||||
void* os_context,
|
||||
dword length,
|
||||
diva_streaming_idi_rx_notify_user_proc_t rx,
|
||||
void* rx_context,
|
||||
const char* trace_ident,
|
||||
struct _diva_segment_alloc* user_segment_alloc) {
|
||||
diva_stream_manager_t* pI;
|
||||
diva_streaming_idi_result_t ret = DivaStreamingIdiResultError;
|
||||
|
||||
#ifdef DIVA_USERMODE
|
||||
dbg_init ("DIVA STREAM", "109-1", 0);
|
||||
#endif
|
||||
|
||||
pI = diva_os_malloc (0, sizeof(*pI));
|
||||
|
||||
if (pI != 0) {
|
||||
memset (pI, 0x00, sizeof(*pI));
|
||||
memcpy(pI->trace_ident, trace_ident, MIN(strlen(trace_ident), DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH));
|
||||
pI->trace_ident[DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH] = 0;
|
||||
|
||||
if (user_segment_alloc != 0) {
|
||||
pI->segment_alloc = user_segment_alloc;
|
||||
pI->user_segment_alloc = 1;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = diva_create_segment_alloc (os_context, &pI->segment_alloc);
|
||||
pI->user_segment_alloc = 0;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
dword number_segments = length/4096 + ((length%4096) != 0);
|
||||
|
||||
pI->segment_alloc_ifc = diva_get_segment_alloc_ifc (pI->segment_alloc);
|
||||
|
||||
ret = diva_streaming_idi_host_ifc_create (&pI->tx, number_segments, pI->segment_alloc, trace_ident);
|
||||
if (ret == 0) {
|
||||
pI->tx_ifc = diva_streaming_idi_host_ifc_get_access (pI->tx);
|
||||
|
||||
ret = diva_streaming_idi_host_rx_ifc_create (&pI->rx, number_segments, pI->segment_alloc, pI->tx, pI->tx_ifc, message_input_proc, pI, &pI->ifc, trace_ident);
|
||||
if (ret == 0) {
|
||||
pI->rx_ifc = diva_streaming_idi_host_rx_ifc_get_access (pI->rx);
|
||||
|
||||
pI->ifc.release = diva_stream_manager_release;
|
||||
pI->ifc.release_stream = diva_stream_manager_release_stream;
|
||||
pI->ifc.write = diva_stream_manager_write;
|
||||
pI->ifc.wakeup = diva_stream_manager_wakeup;
|
||||
pI->ifc.description = diva_stream_manager_description;
|
||||
pI->ifc.sync = diva_stream_manager_sync_req;
|
||||
pI->ifc.flush_stream = diva_stream_flush;
|
||||
pI->ifc.get_tx_free = diva_stream_get_tx_free;
|
||||
pI->ifc.get_tx_in_use = diva_stream_get_tx_in_use;
|
||||
pI->ifc.notify_os_resource_removed = diva_notify_os_resource_removed;
|
||||
|
||||
pI->rx_proc = rx;
|
||||
pI->rx_proc_context = rx_context;
|
||||
|
||||
*ifc = &pI->ifc;
|
||||
ret = DivaStreamingIdiResultOK;
|
||||
} else {
|
||||
DBG_ERR(("failed to create rx stream [%s]", trace_ident))
|
||||
}
|
||||
} else {
|
||||
DBG_ERR(("failed to create tx stream [%s]", trace_ident))
|
||||
}
|
||||
} else {
|
||||
DBG_ERR(("failed to create segment alloc [%s]", trace_ident))
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
diva_stream_manager_release (&pI->ifc);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int message_input_proc (void* user_context, dword message, dword length, const diva_streaming_vector_t* v, dword nr_v) {
|
||||
diva_stream_manager_t* pI = (diva_stream_manager_t*)user_context;
|
||||
|
||||
return (pI->rx_proc (pI->rx_proc_context, message, length, v, nr_v));
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_manager_release (struct _diva_stream* ifc) {
|
||||
if (ifc != 0) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
if (pI->rx != 0)
|
||||
pI->rx_ifc->release (pI->rx);
|
||||
if (pI->tx != 0)
|
||||
pI->tx_ifc->release (pI->tx);
|
||||
if (pI->segment_alloc != 0 && pI->user_segment_alloc == 0)
|
||||
pI->segment_alloc_ifc->release (&pI->segment_alloc);
|
||||
diva_os_free (0, pI);
|
||||
}
|
||||
|
||||
return (DivaStreamingIdiResultOK);
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_manager_release_stream (struct _diva_stream* ifc) {
|
||||
if (ifc != 0) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->release_stream (pI->tx));
|
||||
}
|
||||
|
||||
return (DivaStreamingIdiResultError);
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_manager_write (struct _diva_stream* ifc, dword message, const void* data, dword length) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->write_message (pI->tx, message, data, length));
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_manager_wakeup (struct _diva_stream* ifc) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->rx_ifc->wakeup (pI->rx));
|
||||
}
|
||||
|
||||
const byte* diva_stream_manager_description (struct _diva_stream* ifc, const byte* addie, byte addielen) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
byte length = 4, len_tx, len_rx;
|
||||
|
||||
len_tx = pI->tx_ifc->description (pI->tx, &pI->description[length], sizeof(pI->description)-length);
|
||||
|
||||
if (len_tx != 0) {
|
||||
length += len_tx;
|
||||
len_rx = pI->rx_ifc->description (pI->rx, &pI->description[length], sizeof(pI->description)-length);
|
||||
if (len_rx != 0) {
|
||||
length += len_rx;
|
||||
pI->description[0] = length-1; /* Structure length */
|
||||
pI->description[1] = 0; /* Request */
|
||||
pI->description[2] = len_rx+len_tx+1; /* Structure length */
|
||||
pI->description[3] = 0; /* Version */
|
||||
|
||||
if (addie != 0 && addielen != 0) {
|
||||
byte* description = &pI->description[0];
|
||||
byte* start = &description[3];
|
||||
|
||||
start[0] |= 2U;
|
||||
start = start + start[-1];
|
||||
memcpy (start, addie, addielen);
|
||||
start += addielen;
|
||||
*start++ = 0;
|
||||
|
||||
description[2] += addielen+1;
|
||||
description[0] += addielen+1;
|
||||
length += addielen+1;
|
||||
}
|
||||
|
||||
DBG_TRC(("description length %u [%s]", length, pI->trace_ident))
|
||||
DBG_BLK(((void*)pI->description, length))
|
||||
|
||||
return (&pI->description[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_manager_sync_req (struct _diva_stream* ifc, dword ident) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->sync (pI->tx, ident));
|
||||
}
|
||||
|
||||
static diva_streaming_idi_result_t diva_stream_flush (struct _diva_stream* ifc) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->update_remote (pI->tx) == 0 ? DivaStreamingIdiResultOK : DivaStreamingIdiResultError);
|
||||
}
|
||||
|
||||
static dword diva_stream_get_tx_free (const struct _diva_stream* ifc) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->get_free (pI->tx));
|
||||
}
|
||||
|
||||
static dword diva_stream_get_tx_in_use (const struct _diva_stream* ifc) {
|
||||
const diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, const diva_stream_manager_t, ifc);
|
||||
|
||||
return (pI->tx_ifc->get_in_use (pI->tx));
|
||||
}
|
||||
|
||||
static void diva_notify_os_resource_removed (struct _diva_stream* ifc) {
|
||||
diva_stream_manager_t* pI = DIVAS_CONTAINING_RECORD(ifc, diva_stream_manager_t, ifc);
|
||||
|
||||
if (pI->segment_alloc != 0) {
|
||||
pI->segment_alloc_ifc->resource_removed (pI->segment_alloc);
|
||||
}
|
||||
}
|
||||
|
||||
dword diva_streaming_read_vector_data (const diva_streaming_vector_t* v, int nr_v, dword *vector_offset, dword *vector_position, byte* dst, dword length) {
|
||||
dword to_copy;
|
||||
dword count;
|
||||
|
||||
for (count = 0; vector_offset[0] < ((dword)nr_v) && length != 0;) {
|
||||
to_copy = MIN((v[vector_offset[0]].length - vector_position[0]), length);
|
||||
if (dst != 0) {
|
||||
const byte* tmp = v[vector_offset[0]].data;
|
||||
memcpy (dst, &tmp[vector_position[0]], to_copy);
|
||||
dst += to_copy;
|
||||
}
|
||||
length -= to_copy;
|
||||
count += to_copy;
|
||||
if (v[vector_offset[0]].length == vector_position[0]+to_copy) {
|
||||
vector_offset[0]++;
|
||||
vector_position[0]=0;
|
||||
} else {
|
||||
vector_position[0] += to_copy;
|
||||
}
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
dword diva_streaming_get_indication_data (dword handle, dword message, dword length, const diva_streaming_vector_t* v, int nr_v, byte* pInd, diva_streaming_vector_t* vind, int *pvind_nr) {
|
||||
dword vector_offset = (byte)handle;
|
||||
dword vector_position = handle >> 8;
|
||||
byte Ind = (byte)(message >> 8);
|
||||
byte header[4];
|
||||
dword indication_data_length;
|
||||
int dst_nr_v = *pvind_nr;
|
||||
int i;
|
||||
|
||||
if ((Ind & 0x0f) == 8 /* N_DATA */) {
|
||||
*pInd = Ind;
|
||||
for (i = 0; i < nr_v; i++) {
|
||||
vind[i] = v[i];
|
||||
}
|
||||
*pvind_nr = nr_v;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
Combined indication
|
||||
data[0] = Ind;
|
||||
data[1] = IndCh;
|
||||
data[2] = (byte)length;
|
||||
data[3] = (byte)(length >> 8);
|
||||
*/
|
||||
if (vector_offset >= ((dword)nr_v) || vector_position >= v[vector_offset].length) {
|
||||
DBG_ERR(("%s at %d wrong combined indication format", __FILE__, __LINE__))
|
||||
*pInd = 0;
|
||||
return (0);
|
||||
}
|
||||
{
|
||||
const byte* tmp = v[vector_offset].data;
|
||||
if (tmp[vector_position] == 0) {
|
||||
DBG_ERR(("%s at %d wrong combined indication format", __FILE__, __LINE__))
|
||||
*pInd = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (diva_streaming_read_vector_data (v, nr_v, &vector_offset, &vector_position, header, sizeof(header)) != sizeof(header)) {
|
||||
DBG_ERR(("%s at %d wrong combined indication format", __FILE__, __LINE__))
|
||||
*pInd = 0;
|
||||
return (0);
|
||||
}
|
||||
indication_data_length = ((word)header[2] | (word)header[3] << 8);
|
||||
|
||||
for (i = 0; i < dst_nr_v && indication_data_length != 0; i++) {
|
||||
const byte* tmp = v[vector_offset].data;
|
||||
vind[i].data = &tmp[vector_position];
|
||||
vind[i].length = MIN((v[vector_offset].length - vector_position), indication_data_length);
|
||||
*pvind_nr = i + 1;
|
||||
|
||||
indication_data_length -= vind[i].length;
|
||||
|
||||
if (diva_streaming_read_vector_data (v, nr_v, &vector_offset, &vector_position, 0, vind[i].length) != vind[i].length) {
|
||||
DBG_ERR(("%s at %d wrong combined indication format", __FILE__, __LINE__))
|
||||
*pInd = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (indication_data_length != 0) {
|
||||
DBG_ERR(("%s at %d wrong combined indication format", __FILE__, __LINE__))
|
||||
*pInd = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
*pInd = header[0];
|
||||
|
||||
{
|
||||
const byte* tmp = v[vector_offset].data;
|
||||
if (tmp[vector_position] == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (vector_offset | (vector_position << 8));
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_MANAGER_H__
|
||||
#define __DIVA_STREAMING_MANAGER_H__
|
||||
|
||||
struct _diva_streaming_vector;
|
||||
struct _diva_segment_alloc;
|
||||
|
||||
typedef struct _diva_stream {
|
||||
diva_streaming_idi_result_t (*release)(struct _diva_stream* ifc); /**< destroy stream */
|
||||
diva_streaming_idi_result_t (*release_stream)(struct _diva_stream* ifc); /**< destroy stream */
|
||||
diva_streaming_idi_result_t (*write)(struct _diva_stream* ifc, dword message, const void* data, dword length); /**< write data to stream */
|
||||
diva_streaming_idi_result_t (*wakeup)(struct _diva_stream* ifc);
|
||||
const byte* (*description)(struct _diva_stream* ifc, const byte* addie, byte addielength);
|
||||
diva_streaming_idi_result_t (*sync)(struct _diva_stream* ifc, dword ident);
|
||||
diva_streaming_idi_result_t (*flush_stream)(struct _diva_stream* ifc);
|
||||
dword (*get_tx_free)(const struct _diva_stream* ifc);
|
||||
dword (*get_tx_in_use)(const struct _diva_stream* ifc);
|
||||
void (*notify_os_resource_removed)(struct _diva_stream* ifc);
|
||||
} diva_stream_t;
|
||||
|
||||
/*
|
||||
Message field length one byte
|
||||
*/
|
||||
#define DIVA_STREAM_MESSAGE_TX_DATA 0x00000000 /** Tx data */
|
||||
#define DIVA_STREAM_MESSAGE_TX_DATA_ACK 0x00000001 /** Tx data with ack */
|
||||
#define DIVA_STREAM_MESSAGE_TX_IDI_REQUEST 0x00000002 /** Tx IDI request, request is passed in bits 8...15 */
|
||||
|
||||
#define DIVA_STREAM_MESSAGE_RX_DATA 0x00000000 /** Received data */
|
||||
#define DIVA_STREAM_MESSAGE_RX_TX_FREE 0x00000001 /** Tx space available */
|
||||
#define DIVA_STREAM_MESSAGE_RX_TX_ACK 0x00000002 /** Received Tx Ack message */
|
||||
#define DIVA_STREAM_MESSAGE_INIT 0x00000003 /** Stream init complete */
|
||||
#define DIVA_STREAM_MESSAGE_SYNC_ACK 0x00000004 /** Received stream sync ack */
|
||||
#define DIVA_STREAM_MESSAGE_RELEASE_ACK 0x00000005 /** Received stream release acknowledge */
|
||||
#define DIVA_STREAM_MESSAGE_INIT_ERROR 0x00000007 /** Stream init error */
|
||||
#define DIVA_STREAM_MESSAGE_RELEASED 0x00000008 /** Not message, used internally */
|
||||
|
||||
#define DIVA_STREAMING_MANAGER_HOST_USER_MODE_STREAM 0x40000000U
|
||||
#define DIVA_STREAMING_MANAGER_TX_COUNTER_IN_TX_PAGE 0x20000000U /* Tx counter is located at end of TX page */
|
||||
|
||||
diva_streaming_idi_result_t diva_stream_create_with_user_segment_alloc (struct _diva_stream** ifc,
|
||||
void* os_context,
|
||||
dword length,
|
||||
diva_streaming_idi_rx_notify_user_proc_t rx,
|
||||
void* rx_context,
|
||||
const char* trace_ident,
|
||||
struct _diva_segment_alloc* user_segment_alloc);
|
||||
diva_streaming_idi_result_t diva_stream_create (struct _diva_stream** ifc,
|
||||
void* os_context,
|
||||
dword length,
|
||||
diva_streaming_idi_rx_notify_user_proc_t rx,
|
||||
void* rx_context,
|
||||
const char* trace_ident);
|
||||
|
||||
dword diva_streaming_read_vector_data (const diva_streaming_vector_t* v, int nr_v, dword *vector_offset, dword *vector_position, byte* dst, dword length);
|
||||
dword diva_streaming_get_indication_data (dword handle, dword message, dword length, const diva_streaming_vector_t* v, int nr_v, byte* pInd, diva_streaming_vector_t* vind, int *pvind_nr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "pc.h"
|
||||
#include "diva_streaming_messages.h"
|
||||
|
||||
int diva_streaming_idi_supported_ind (byte idiInd, dword length, const byte* data) {
|
||||
byte Ind = idiInd & 0x0f;
|
||||
|
||||
if (likely(Ind == N_DATA))
|
||||
return (1);
|
||||
|
||||
if (Ind == N_UDATA && length != 0) {
|
||||
switch (*data) {
|
||||
case UDATA_INDICATION_DTMF_DIGITS_SENT:
|
||||
case UDATA_INDICATION_DTMF_DIGITS_RECEIVED:
|
||||
case UDATA_INDICATION_MIXER_TAP_DATA:
|
||||
case UDATA_INDICATION_RTCP_PACKET:
|
||||
case UDATA_INDICATION_RTCP_GENERATED:
|
||||
case UDATA_INDICATION_RTCP_ACCEPTED:
|
||||
case UDATA_INDICATION_FEC_PACKET:
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int diva_streaming_idi_supported_req (byte idiReq, dword length, const byte* data) {
|
||||
byte Req = idiReq & 0x0f;
|
||||
|
||||
if (likely(Req == N_DATA))
|
||||
return (1);
|
||||
|
||||
if (Req == N_UDATA && length != 0) {
|
||||
switch (*data) {
|
||||
case UDATA_REQUEST_SEND_DTMF_DIGITS:
|
||||
case UDATA_REQUEST_MIXER_TAP_DATA:
|
||||
case UDATA_REQUEST_RTCP_PACKET:
|
||||
case UDATA_REQUEST_RTCP_GENERATE:
|
||||
case UDATA_REQUEST_RTCP_ACCEPT:
|
||||
case UDATA_REQUEST_FEC_PACKET:
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_MESSAGES_H__
|
||||
#define __DIVA_STREAMING_MESSAGES_H__
|
||||
|
||||
/*
|
||||
* Tx direction (to IDI)
|
||||
*/
|
||||
#define DIVA_STREAMING_IDI_SYSTEM_MESSAGE 0x80000000U
|
||||
#define DIVA_STREAMING_IDI_RX_ACK_MSG 0x02 /* Ack processed by host data */
|
||||
#define DIVA_STREAMING_IDI_SYNC_REQ 0x03 /* Sync request */
|
||||
#define DIVA_STREAMING_IDI_RELEASE 0x04 /* Release stream */
|
||||
#define DIVA_STREAMING_IDI_SET_DEBUG_IDENT 0x05 /* Set debug ident */
|
||||
#define DIVA_STREAMING_IDI_TX_REQUEST 0x07
|
||||
|
||||
|
||||
/*
|
||||
* Rx direction (to host)
|
||||
*/
|
||||
#define DIVA_STREAMING_IDI_TX_INIT_MSG 0x01 /* Init message, created version, counter address */
|
||||
#define DIVA_STREAMING_IDI_TX_INIT_MSG_LENGTH 15
|
||||
#define DIVA_STREAMING_IDI_TX_ACK_MSG 0x02 /* Ack processed by tx data */
|
||||
#define DIVA_STREAMING_IDI_TX_ACK_MSG_LENGTH 0x09
|
||||
#define DIVA_STREAMING_IDI_TX_SYNC_ACK 0x03 /* Sync request acknowledge */
|
||||
#define DIVA_STREAMING_IDI_TX_SYNC_ACK_LENGTH 0x0a
|
||||
#define DIVA_STREAMING_IDI_RELEASE_ACK 0x04
|
||||
#define DIVA_STREAMING_IDI_RELEASE_ACK_LENGTH 0x08
|
||||
#define DIVA_STREAMING_IDI_TX_INIT_ERROR 0x05
|
||||
#define DIVA_STREAMING_IDI_TX_INIT_ERROR_LENGTH 0x0a
|
||||
|
||||
|
||||
#ifndef UDATA_REQUEST_SEND_DTMF_DIGITS
|
||||
#define UDATA_REQUEST_SEND_DTMF_DIGITS 16
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_DTMF_DIGITS_SENT
|
||||
#define UDATA_INDICATION_DTMF_DIGITS_SENT 16
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_DTMF_DIGITS_RECEIVED
|
||||
#define UDATA_INDICATION_DTMF_DIGITS_RECEIVED 17
|
||||
#endif
|
||||
|
||||
#ifndef UDATA_REQUEST_MIXER_TAP_DATA
|
||||
#define UDATA_REQUEST_MIXER_TAP_DATA 27
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_MIXER_TAP_DATA
|
||||
#define UDATA_INDICATION_MIXER_TAP_DATA 27
|
||||
#endif
|
||||
|
||||
#ifndef UDATA_REQUEST_RTCP_PACKET
|
||||
#define UDATA_REQUEST_RTCP_PACKET 67
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_RTCP_PACKET
|
||||
#define UDATA_INDICATION_RTCP_PACKET 67
|
||||
#endif
|
||||
|
||||
#ifndef UDATA_REQUEST_RTCP_GENERATE
|
||||
#define UDATA_REQUEST_RTCP_GENERATE 68
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_RTCP_GENERATED
|
||||
#define UDATA_INDICATION_RTCP_GENERATED 68
|
||||
#endif
|
||||
#ifndef UDATA_REQUEST_RTCP_ACCEPT
|
||||
#define UDATA_REQUEST_RTCP_ACCEPT 69
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_RTCP_ACCEPTED
|
||||
#define UDATA_INDICATION_RTCP_ACCEPTED 69
|
||||
#endif
|
||||
|
||||
#ifndef UDATA_REQUEST_FEC_PACKET
|
||||
#define UDATA_REQUEST_FEC_PACKET 70
|
||||
#endif
|
||||
#ifndef UDATA_INDICATION_FEC_PACKET
|
||||
#define UDATA_INDICATION_FEC_PACKET 70
|
||||
#endif
|
||||
|
||||
int diva_streaming_idi_supported_ind (byte idiInd, dword length, const byte* data);
|
||||
int diva_streaming_idi_supported_req (byte idiReq, dword length, const byte* data);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_RESULT_H__
|
||||
#define __DIVA_STREAMING_RESULT_H__
|
||||
|
||||
typedef enum {
|
||||
DivaStreamingIdiResultOK = 0,
|
||||
DivaStreamingIdiResultError = -1,
|
||||
DivaStreamingIdiResultBusy = -2
|
||||
} diva_streaming_idi_result_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_STREAMING_VECTOR_H__
|
||||
#define __DIVA_STREAMING_VECTOR_H__
|
||||
|
||||
typedef struct _diva_streaming_vector {
|
||||
const void* data;
|
||||
dword length;
|
||||
} diva_streaming_vector_t;
|
||||
|
||||
typedef int (*diva_streaming_idi_rx_notify_user_proc_t)(void* user_context, dword message, dword length, const struct _diva_streaming_vector* v, dword nr_v);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,932 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef PC_H_INCLUDED /* { */
|
||||
#define PC_H_INCLUDED
|
||||
/*------------------------------------------------------------------*/
|
||||
/* buffer definition */
|
||||
/*------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
word length; /* length of data/parameter field */
|
||||
byte P[270]; /* data/parameter field */
|
||||
} PBUFFER;
|
||||
/*------------------------------------------------------------------*/
|
||||
/* dual port ram structure */
|
||||
/*------------------------------------------------------------------*/
|
||||
struct dual
|
||||
{
|
||||
byte Req; /* request register */
|
||||
byte ReqId; /* request task/entity identification */
|
||||
byte Rc; /* return code register */
|
||||
byte RcId; /* return code task/entity identification */
|
||||
byte Ind; /* Indication register */
|
||||
byte IndId; /* Indication task/entity identification */
|
||||
byte IMask; /* Interrupt Mask Flag */
|
||||
byte RNR; /* Receiver Not Ready (set by PC) */
|
||||
byte XLock; /* XBuffer locked Flag */
|
||||
byte Int; /* ISDN-S interrupt */
|
||||
byte ReqCh; /* Channel field for layer-3 Requests */
|
||||
byte RcCh; /* Channel field for layer-3 Returncodes */
|
||||
byte IndCh; /* Channel field for layer-3 Indications */
|
||||
byte MInd; /* more data indication field */
|
||||
word MLength; /* more data total packet length */
|
||||
byte ReadyInt; /* request field for ready interrupt */
|
||||
byte SWReg; /* Software register for special purposes */
|
||||
byte Reserved[11]; /* reserved space */
|
||||
byte InterfaceType; /* interface type 1=16K interface */
|
||||
word Signature; /* ISDN-S adapter Signature (GD) */
|
||||
PBUFFER XBuffer; /* Transmit Buffer */
|
||||
PBUFFER RBuffer; /* Receive Buffer */
|
||||
};
|
||||
/*------------------------------------------------------------------*/
|
||||
/* SWReg Values (0 means no command) */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define SWREG_DIE_WITH_LEDON 0x01
|
||||
#define SWREG_HALT_CPU 0x02 /* Push CPU into a while(1) loop */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Id Fields Coding */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define IDI_ID_MASK 0xe0 /* Mask for the ID field */
|
||||
#define GL_ERR_ID 0x1f /* ID for error reporting on global requests*/
|
||||
#define DSIG_ID 0x00 /* ID for D-channel signaling */
|
||||
#define NL_ID 0x20 /* ID for network-layer access (B or D) */
|
||||
#define BLLC_ID 0x60 /* ID for B-channel link level access */
|
||||
#define TASK_ID 0x80 /* ID for dynamic user tasks */
|
||||
#define TIMER_ID 0xa0 /* ID for timer task */
|
||||
#define TEL_ID 0xc0 /* ID for telephone support */
|
||||
#define MAN_ID 0xe0 /* ID for management */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* ASSIGN and REMOVE requests are the same for all entities */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define ASSIGN 0x01
|
||||
#define UREMOVE 0xfe /* without return code */
|
||||
#define REMOVE 0xff
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Timer Interrupt Task Interface */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define ASSIGN_TIM 0x01
|
||||
#define REMOVE_TIM 0xff
|
||||
/*------------------------------------------------------------------*/
|
||||
/* dynamic user task interface */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define ASSIGN_TSK 0x01
|
||||
#define REMOVE_TSK 0xff
|
||||
#define LOAD 0xf0
|
||||
#define RELOCATE 0xf1
|
||||
#define START 0xf2
|
||||
#define LOAD2 0xf3
|
||||
#define RELOCATE2 0xf4
|
||||
/*------------------------------------------------------------------*/
|
||||
/* dynamic user task messages */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define TSK_B2 0x0000
|
||||
#define TSK_WAKEUP 0x2000
|
||||
#define TSK_TIMER 0x4000
|
||||
#define TSK_TSK 0x6000
|
||||
#define TSK_PC 0xe000
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LL management primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define ASSIGN_LL 1 /* assign logical link */
|
||||
#define REMOVE_LL 0xff /* remove logical link */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* LL service primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define LL_UDATA 1 /* link unit data request/indication */
|
||||
#define LL_ESTABLISH 2 /* link establish request/indication */
|
||||
#define LL_RELEASE 3 /* link release request/indication */
|
||||
#define LL_DATA 4 /* data request/indication */
|
||||
#define LL_LOCAL 5 /* switch to local operation (COM only) */
|
||||
#define LL_DATA_PEND 5 /* data pending indication (SDLC SHM only) */
|
||||
#define LL_REMOTE 6 /* switch to remote operation (COM only) */
|
||||
#define LL_TEST 8 /* link test request */
|
||||
#define LL_MDATA 9 /* more data request/indication */
|
||||
#define LL_BUDATA 10 /* broadcast unit data request/indication */
|
||||
#define LL_XID 12 /* XID command request/indication */
|
||||
#define LL_XID_R 13 /* XID response request/indication */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* NL service primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define N_MDATA 1 /* more data to come REQ/IND */
|
||||
#define N_CONNECT 2 /* OSI N-CONNECT REQ/IND */
|
||||
#define N_CONNECT_ACK 3 /* OSI N-CONNECT CON/RES */
|
||||
#define N_DISC 4 /* OSI N-DISC REQ/IND */
|
||||
#define N_DISC_ACK 5 /* OSI N-DISC CON/RES */
|
||||
#define N_RESET 6 /* OSI N-RESET REQ/IND */
|
||||
#define N_RESET_ACK 7 /* OSI N-RESET CON/RES */
|
||||
#define N_DATA 8 /* OSI N-DATA REQ/IND */
|
||||
#define N_EDATA 9 /* OSI N-EXPEDITED DATA REQ/IND */
|
||||
#define N_UDATA 10 /* OSI D-UNIT-DATA REQ/IND */
|
||||
#define N_BDATA 11 /* BROADCAST-DATA REQ/IND */
|
||||
#define N_DATA_ACK 12 /* data ack ind for D-bit procedure */
|
||||
#define N_EDATA_ACK 13 /* data ack ind for INTERRUPT */
|
||||
#define N_XON 15 /* clear RNR state */
|
||||
#define N_COMBI_IND N_XON /* combined indication */
|
||||
#define N_Q_BIT 0x10 /* Q-bit for req/ind */
|
||||
#define N_M_BIT 0x20 /* M-bit for req/ind */
|
||||
#define N_D_BIT 0x40 /* D-bit for req/ind */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Signaling management primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define ASSIGN_SIG 1 /* assign signaling task */
|
||||
#define UREMOVE_SIG 0xfe /* remove signaling task without return code*/
|
||||
#define REMOVE_SIG 0xff /* remove signaling task */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Signaling service primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define CALL_REQ 1 /* call request */
|
||||
#define CALL_CON 1 /* call confirmation */
|
||||
#define CALL_IND 2 /* incoming call connected */
|
||||
#define LISTEN_REQ 2 /* listen request */
|
||||
#define HANGUP 3 /* hangup request/indication */
|
||||
#define SUSPEND 4 /* call suspend request/confirm */
|
||||
#define RESUME 5 /* call resume request/confirm */
|
||||
#define SUSPEND_REJ 6 /* suspend rejected indication */
|
||||
#define USER_DATA 8 /* user data for user to user signaling */
|
||||
#define CONGESTION 9 /* network congestion indication */
|
||||
#define INDICATE_REQ 10 /* request to indicate an incoming call */
|
||||
#define INDICATE_IND 10 /* indicates that there is an incoming call */
|
||||
#define CALL_RES 11 /* accept an incoming call */
|
||||
#define CALL_ALERT 12 /* send ALERT for incoming call */
|
||||
#define INFO_REQ 13 /* INFO request */
|
||||
#define INFO_IND 13 /* INFO indication */
|
||||
#define REJECT 14 /* reject an incoming call */
|
||||
#define RESOURCES 15 /* reserve B-Channel hardware resources */
|
||||
#define HW_CTRL 16 /* B-Channel hardware IOCTL req/ind */
|
||||
#define TEL_CTRL 16 /* Telephone control request/indication */
|
||||
#define STATUS_REQ 17 /* Request D-State (returned in INFO_IND) */
|
||||
#define FAC_REG_REQ 18 /* 1TR6 connection independent fac reg */
|
||||
#define FAC_REG_ACK 19 /* 1TR6 fac registration acknowledge */
|
||||
#define FAC_REG_REJ 20 /* 1TR6 fac registration reject */
|
||||
#define CALL_COMPLETE 21/* send a CALL_PROC for incoming call */
|
||||
#define SW_CTRL 22 /* extended software features */
|
||||
#define REGISTER_REQ 23 /* Q.931 connection independent reg req */
|
||||
#define REGISTER_IND 24 /* Q.931 connection independent reg ind */
|
||||
#define FACILITY_REQ 25 /* Q.931 connection independent fac req */
|
||||
#define FACILITY_IND 26 /* Q.931 connection independent fac ind */
|
||||
#define NCR_INFO_REQ 27 /* INFO_REQ with NULL CR */
|
||||
#define GCR_MIM_REQ 28 /* MANAGEMENT_INFO_REQ with global CR */
|
||||
#define SIG_CTRL 29 /* Control for Signalling Hardware */
|
||||
#define DSP_CTRL 30 /* Control for DSPs */
|
||||
#define LAW_REQ 31 /* Law config request for (returns info_i) */
|
||||
#define SPID_CTRL 32 /* Request/indication SPID related */
|
||||
#define NCR_FACILITY 33 /* Request/indication with NULL/DUMMY CR */
|
||||
#define CALL_HOLD 34 /* Request/indication to hold a CALL */
|
||||
#define CALL_RETRIEVE 35 /* Request/indication to retrieve a CALL */
|
||||
#define CALL_HOLD_ACK 36 /* OK of hold a CALL */
|
||||
#define CALL_RETRIEVE_ACK 37 /* OK of retrieve a CALL */
|
||||
#define CALL_HOLD_REJ 38 /* Reject of hold a CALL */
|
||||
#define CALL_RETRIEVE_REJ 39 /* Reject of retrieve a call */
|
||||
#define GCR_RESTART 40 /* Send/Receive Restart message */
|
||||
#define S_SERVICE 41 /* Send/Receive Supplementary Service */
|
||||
#define S_SERVICE_REJ 42 /* Reject Supplementary Service indication */
|
||||
#define S_SUPPORTED 43 /* Req/Ind to get Supported Services */
|
||||
#define STATUS_ENQ 44 /* Req to send the D-ch request if !state0 */
|
||||
#define CALL_GUARD 45 /* Req/Ind to use the FLAGS_CALL_OUTCHECK */
|
||||
#define CALL_GUARD_HP 46 /* Call Guard function to reject a call */
|
||||
#define CALL_GUARD_IF 47 /* Call Guard function, inform the appl */
|
||||
#define SSEXT_REQ 48 /* Supplem.Serv./QSIG specific request */
|
||||
#define SSEXT_IND 49 /* Supplem.Serv./QSIG specific indication */
|
||||
/* reserved commands for the US protocols */
|
||||
#define INT_3PTY_NIND 50 /* US specific indication */
|
||||
#define INT_CF_NIND 51 /* US specific indication */
|
||||
#define INT_3PTY_DROP 52 /* US specific indication */
|
||||
#define INT_MOVE_CONF 53 /* US specific indication */
|
||||
#define INT_MOVE_RC 54 /* US specific indication */
|
||||
#define INT_MOVE_FLIPPED_CONF 55 /* US specific indication */
|
||||
#define INT_X5NI_OK 56 /* internal transfer OK indication */
|
||||
#define INT_XDMS_START 57 /* internal transfer OK indication */
|
||||
#define INT_XDMS_STOP 58 /* internal transfer finish indication */
|
||||
#define INT_XDMS_STOP2 59 /* internal transfer send FA */
|
||||
#define INT_CUSTCONF_REJ 60 /* internal conference reject */
|
||||
#define INT_CUSTXFER 61 /* internal transfer request */
|
||||
#define INT_CUSTX_NIND 62 /* internal transfer ack */
|
||||
#define INT_CUSTXREJ_NIND 63 /* internal transfer rej */
|
||||
#define INT_X5NI_CF_XFER 64 /* internal transfer OK indication */
|
||||
#define VSWITCH_REQ 65 /* communication between protocol and */
|
||||
#define VSWITCH_IND 66 /* capifunctions for D-CH-switching */
|
||||
#define MWI_POLL 67 /* Message Waiting Status Request fkt */
|
||||
#define CALL_PEND_NOTIFY 68 /* notify capi to set new listen */
|
||||
#define DO_NOTHING 69 /* dont do somethin if you get this */
|
||||
#define INT_CT_REJ 70 /* ECT rejected internal command */
|
||||
#define CALL_HOLD_COMPLETE 71 /* In NT Mode indicate hold complete */
|
||||
#define CALL_RETRIEVE_COMPLETE 72 /* In NT Mode indicate retrieve complete */
|
||||
#define RESERVE_REQ 73 /* Request to reserve resources */
|
||||
#define RESERVE_IND 73 /* Indication for granted resources */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* management service primitives */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define MAN_READ 2
|
||||
#define MAN_WRITE 3
|
||||
#define MAN_EXECUTE 4
|
||||
#define MAN_EVENT_ON 5
|
||||
#define MAN_EVENT_OFF 6
|
||||
#define MAN_LOCK 7
|
||||
#define MAN_UNLOCK 8
|
||||
#define MAN_INFO_IND 2
|
||||
#define MAN_EVENT_IND 3
|
||||
#define MAN_TRACE_IND 4
|
||||
#define MAN_COMBI_IND 9
|
||||
#define MAN_ESC 0x80
|
||||
/*------------------------------------------------------------------*/
|
||||
/* return code coding */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define UNKNOWN_COMMAND 0x01 /* unknown command */
|
||||
#define WRONG_COMMAND 0x02 /* wrong command */
|
||||
#define WRONG_ID 0x03 /* unknown task/entity id */
|
||||
#define WRONG_CH 0x04 /* wrong task/entity id */
|
||||
#define UNKNOWN_IE 0x05 /* unknown information el. */
|
||||
#define WRONG_IE 0x06 /* wrong information el. */
|
||||
#define OUT_OF_RESOURCES 0x07 /* ISDN-S card out of res. */
|
||||
#define OUT_OF_LICENSES 0x08 /* ISDN-S card out of res. */
|
||||
#define ISDN_GUARD_REJ 0x09 /* ISDN-Guard SuppServ rej */
|
||||
#define N_FLOW_CONTROL 0x10 /* Flow-Control, retry */
|
||||
#define ASSIGN_RC 0xe0 /* ASSIGN acknowledgement */
|
||||
#define ASSIGN_OK 0xef /* ASSIGN OK */
|
||||
#define OK_FC 0xfc /* Flow-Control RC */
|
||||
#define READY_INT 0xfd /* Ready interrupt */
|
||||
#define TIMER_INT 0xfe /* timer interrupt */
|
||||
#define OK 0xff /* command accepted */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* information elements */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define SHIFT 0x90 /* codeset shift */
|
||||
#define MORE 0xa0 /* more data */
|
||||
#define SDNCMPL 0xa1 /* sending complete */
|
||||
#define CL 0xb0 /* congestion level */
|
||||
/* codeset 0 */
|
||||
#define SMSG 0x00 /* segmented message */
|
||||
#define BC 0x04 /* Bearer Capability */
|
||||
#define CAU 0x08 /* cause */
|
||||
#define CAD 0x0c /* Connected address */
|
||||
#define CAI 0x10 /* call identity */
|
||||
#define CHI 0x18 /* channel identification */
|
||||
#define LLI 0x19 /* logical link id */
|
||||
#define CHA 0x1a /* charge advice */
|
||||
#define FTY 0x1c /* Facility */
|
||||
#define DT 0x29 /* ETSI date/time */
|
||||
#define KEY 0x2c /* keypad information element */
|
||||
#define UID 0x2d /* User id information element */
|
||||
#define DSP 0x28 /* display */
|
||||
#define SIG 0x34 /* signalling hardware control */
|
||||
#define OAD 0x6c /* origination address */
|
||||
#define OSA 0x6d /* origination sub-address */
|
||||
#define CPN 0x70 /* called party number */
|
||||
#define DSA 0x71 /* destination sub-address */
|
||||
#define RDX 0x73 /* redirecting number extended */
|
||||
#define RDN 0x74 /* redirecting number */
|
||||
#define RIN 0x76 /* redirection number */
|
||||
#define IUP 0x76 /* VN6 rerouter->PCS (codeset 6) */
|
||||
#define IPU 0x77 /* VN6 PCS->rerouter (codeset 6) */
|
||||
#define RI 0x79 /* restart indicator */
|
||||
#if defined(MIE)
|
||||
#undef MIE
|
||||
#endif
|
||||
#define MIE 0x7a /* management info element */
|
||||
#define LLC 0x7c /* low layer compatibility */
|
||||
#define HLC 0x7d /* high layer compatibility */
|
||||
#define UUI 0x7e /* user user information */
|
||||
#define ESC 0x7f /* escape extension */
|
||||
#define DLC 0x20 /* data link layer configuration */
|
||||
#define NLC 0x21 /* network layer configuration */
|
||||
#define REDIRECT_IE 0x22 /* redirection request/indication data */
|
||||
#define REDIRECT_NET_IE 0x23 /* redirection network override data */
|
||||
/* codeset 6 */
|
||||
#define SIN 0x01 /* service indicator */
|
||||
#define CIF 0x02 /* charging information */
|
||||
#define DATE 0x03 /* date */
|
||||
#define CPS 0x07 /* called party status */
|
||||
#define OLINE 0x01 /* codeset 6, ANI II used in US networks - e.g. verizon - feature group D */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* ESC information elements */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define MSGTYPEIE 0x7a /* Messagetype info element */
|
||||
#define CRIE 0x7b /* INFO info element */
|
||||
#define CODESET6IE 0xec /* Tunnel for Codeset 6 IEs */
|
||||
#define VSWITCHIE 0xed /* VSwitch info element */
|
||||
#define SSEXTIE 0xee /* Supplem. Service info element */
|
||||
#define PROFILEIE 0xef /* Profile info element */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Extended cause codes */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define GUARD_ERROR 0x05
|
||||
#define L1_ERROR 0x08
|
||||
#define TEI_ERROR 0x09
|
||||
#define L2_ERROR 0x0a
|
||||
#define L3_ERROR 0x0b
|
||||
#define OUT_OF_RESOURCES_ERROR 0x0c
|
||||
#define OUT_OF_LICENSES_ERROR 0x0d
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Supplementary Services Misc Defines */
|
||||
/* some defines that are only used in protocol are defined in q931.h*/
|
||||
/*------------------------------------------------------------------*/
|
||||
#define SSTRANSPORT 0x000d
|
||||
#define HOLD_NOTIFY 0x00
|
||||
#define RETRIEVE_NOTIFY 0x01
|
||||
#define SCS7IE_IND 0x02
|
||||
#define SCNT_IND 0x03
|
||||
#define CARDIDENT_IND 0x04
|
||||
#define LINKIDENT_IND 0x05
|
||||
#define SSTUNNEL 0x000f
|
||||
#define SSIDENTIFIER 0x0010
|
||||
#define CQ_PRIDENT 0x0011
|
||||
#define CQ_PRCALLDETAILS 0x0012
|
||||
/*------------------------------------------------------------------*/
|
||||
/* TEL_CTRL contents */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define RING_ON 0x01
|
||||
#define RING_OFF 0x02
|
||||
#define HANDS_FREE_ON 0x03
|
||||
#define HANDS_FREE_OFF 0x04
|
||||
#define ON_HOOK 0x80
|
||||
#define OFF_HOOK 0x90
|
||||
/* operation values used by ETSI supplementary services */
|
||||
#define THREE_PTY_BEGIN 0x04
|
||||
#define THREE_PTY_END 0x05
|
||||
#define ECT_EXECUTE 0x06
|
||||
#define ACTIVATION_DIVERSION 0x07
|
||||
#define DEACTIVATION_DIVERSION 0x08
|
||||
#define CALL_DEFLECTION 0x0D
|
||||
#define INTERROGATION_DIVERSION 0x0B
|
||||
#define INTERROGATION_SERV_USR_NR 0x11
|
||||
#define ACTIVATION_MWI 0x20
|
||||
#define DEACTIVATION_MWI 0x21
|
||||
#define MWI_INDICATION 0x22
|
||||
#define MWI_RESPONSE 0x23
|
||||
#define CONF_BEGIN 0x28
|
||||
#define CONF_ADD 0x29
|
||||
#define CONF_SPLIT 0x2a
|
||||
#define CONF_DROP 0x2b
|
||||
#define CONF_ISOLATE 0x2c
|
||||
#define CONF_REATTACH 0x2d
|
||||
#define CONF_PARTYDISC 0x2e
|
||||
#define CCBS_INFO_RETAIN 0x2f
|
||||
#define CCBS_ERASECALLLINKAGEID 0x30
|
||||
#define CCBS_STOP_ALERTING 0x31
|
||||
#define CCBS_REQUEST 0x32
|
||||
#define CCBS_DEACTIVATE 0x33
|
||||
#define CCBS_INTERROGATE 0x34
|
||||
#define CCBS_STATUS 0x35
|
||||
#define CCBS_ERASE 0x36
|
||||
#define CCBS_B_FREE 0x37
|
||||
#define CCNR_INFO_RETAIN 0x38
|
||||
#define CCBS_REMOTE_USER_FREE 0x39
|
||||
#define CCNR_REQUEST 0x3a
|
||||
#define CCNR_INTERROGATE 0x3b
|
||||
#define CCBS_IN_SET_CB 0x3c
|
||||
#define CCBS_IN_CLEAR_CB 0x3d
|
||||
#define CCBS_IN_AVAILABLE 0x3e
|
||||
#define GET_SUPPORTED_SERVICES 0xff
|
||||
#define DIVERSION_PROCEDURE_CFU 0x70
|
||||
#define DIVERSION_PROCEDURE_CFB 0x71
|
||||
#define DIVERSION_PROCEDURE_CFNR 0x72
|
||||
#define DIVERSION_DEACTIVATION_CFU 0x80
|
||||
#define DIVERSION_DEACTIVATION_CFB 0x81
|
||||
#define DIVERSION_DEACTIVATION_CFNR 0x82
|
||||
#define DIVERSION_INTERROGATE_NUM 0x11
|
||||
#define DIVERSION_INTERROGATE_CFU 0x60
|
||||
#define DIVERSION_INTERROGATE_CFB 0x61
|
||||
#define DIVERSION_INTERROGATE_CFNR 0x62
|
||||
/* Service Masks */
|
||||
#define SMASK_HOLD_RETRIEVE 0x00000001
|
||||
#define SMASK_TERMINAL_PORTABILITY 0x00000002
|
||||
#define SMASK_ECT 0x00000004
|
||||
#define SMASK_3PTY 0x00000008
|
||||
#define SMASK_CALL_FORWARDING 0x00000010
|
||||
#define SMASK_CALL_DEFLECTION 0x00000020
|
||||
#define SMASK_MCID 0x00000040
|
||||
#define SMASK_CCBS 0x00000080
|
||||
#define SMASK_MWI 0x00000100
|
||||
#define SMASK_CCNR 0x00000200
|
||||
#define SMASK_CONF 0x00000400
|
||||
/* ----------------------------------------------
|
||||
Types of transfers used to transfer the
|
||||
information in the 'struct RC->Reserved2[8]'
|
||||
The information is transferred as 2 dwords
|
||||
(2 4Byte unsigned values)
|
||||
First of them is the transfer type.
|
||||
2^32-1 possible messages are possible in this way.
|
||||
The context of the second one had no meaning
|
||||
---------------------------------------------- */
|
||||
#define DIVA_RC_TYPE_NONE 0x00000000
|
||||
#define DIVA_RC_TYPE_REMOVE_COMPLETE 0x00000008
|
||||
#define DIVA_RC_TYPE_STREAM_PTR 0x00000009
|
||||
#define DIVA_RC_TYPE_CMA_PTR 0x0000000a
|
||||
#define DIVA_RC_TYPE_OK_FC 0x0000000b
|
||||
#define DIVA_RC_TYPE_RX_DMA 0x0000000c
|
||||
/* ------------------------------------------------------
|
||||
IO Control codes for IN BAND SIGNALING
|
||||
------------------------------------------------------ */
|
||||
#define CTRL_L1_SET_SIG_ID 5
|
||||
#define CTRL_L1_SET_DAD 6
|
||||
#define CTRL_L1_RESOURCES 7
|
||||
/* ------------------------------------------------------ */
|
||||
/* ------------------------------------------------------
|
||||
Layer 2 types
|
||||
------------------------------------------------------ */
|
||||
#define X75T 1 /* x.75 for ttx */
|
||||
#define TRF 2 /* transparent with hdlc framing */
|
||||
#define TRF_IN 3 /* transparent with hdlc fr. inc. */
|
||||
#define SDLC 4 /* sdlc, sna layer-2 */
|
||||
#define X75 5 /* x.75 for btx */
|
||||
#define LAPD 6 /* lapd (Q.921) */
|
||||
#define X25_L2 7 /* x.25 layer-2 */
|
||||
#define V120_L2 8 /* V.120 layer-2 protocol */
|
||||
#define V42_IN 9 /* V.42 layer-2 protocol, incomming */
|
||||
#define V42 10 /* V.42 layer-2 protocol */
|
||||
#define MDM_ATP 11 /* AT Parser built in the L2 */
|
||||
#define X75_V42BIS 12 /* x.75 with V.42bis */
|
||||
#define RTPL2_IN 13 /* RTP layer-2 protocol, incomming */
|
||||
#define RTPL2 14 /* RTP layer-2 protocol */
|
||||
#define V120_V42BIS 15 /* V.120 asynchronous mode supporting V.42bis compression */
|
||||
#define T38 16 /* T38 layer-2 protocol */
|
||||
#define T38_IN 17 /* T38 layer-2 protocol */
|
||||
#define LISTENER 27 /* Layer 2 to listen line */
|
||||
#define MTP2 28 /* MTP2 Layer 2 */
|
||||
#define PIAFS_CRC 29 /* PIAFS Layer 2 with CRC calculation at L2 */
|
||||
/* ------------------------------------------------------
|
||||
PIAFS DLC DEFINITIONS
|
||||
------------------------------------------------------ */
|
||||
#define PIAFS_64K 0x01
|
||||
#define PIAFS_VARIABLE_SPEED 0x02
|
||||
#define PIAFS_CHINESE_SPEED 0x04
|
||||
#define PIAFS_UDATA_ABILITY_ID 0x80
|
||||
#define PIAFS_UDATA_ABILITY_DCDON 0x01
|
||||
#define PIAFS_UDATA_ABILITY_DDI 0x80
|
||||
/*
|
||||
DLC of PIAFS :
|
||||
Byte | 8 7 6 5 4 3 2 1
|
||||
-----+--------------------------------------------------------
|
||||
0 | 0 0 1 0 0 0 0 0 Data Link Configuration
|
||||
1 | X X X X X X X X Length of IE (at least 15 Bytes)
|
||||
2 | 0 0 0 0 0 0 0 0 max. information field, LOW byte (not used, fix 73 Bytes)
|
||||
3 | 0 0 0 0 0 0 0 0 max. information field, HIGH byte (not used, fix 73 Bytes)
|
||||
4 | 0 0 0 0 0 0 0 0 address A (not used)
|
||||
5 | 0 0 0 0 0 0 0 0 address B (not used)
|
||||
6 | 0 0 0 0 0 0 0 0 Mode (not used, fix 128)
|
||||
7 | 0 0 0 0 0 0 0 0 Window Size (not used, fix 127)
|
||||
8 | X X X X X X X X XID Length, Low Byte (at least 7 Bytes)
|
||||
9 | X X X X X X X X XID Length, High Byte
|
||||
10 | 0 0 0 0 0 C V S PIAFS Protocol Speed configuration -> Note(1)
|
||||
| S = 0 -> Protocol Speed is 32K
|
||||
| S = 1 -> Protocol Speed is 64K
|
||||
| V = 0 -> Protocol Speed is fixed
|
||||
| V = 1 -> Protocol Speed is variable
|
||||
| C = 0 -> speed setting according to standard
|
||||
| C = 1 -> speed setting for chinese implementation
|
||||
11 | 0 0 0 0 0 0 R T P0 - V42bis Compression enable/disable, Low Byte
|
||||
| T = 0 -> Transmit Direction enable
|
||||
| T = 1 -> Transmit Direction disable
|
||||
| R = 0 -> Receive Direction enable
|
||||
| R = 1 -> Receive Direction disable
|
||||
13 | 0 0 0 0 0 0 0 0 P0 - V42bis Compression enable/disable, High Byte
|
||||
14 | X X X X X X X X P1 - V42bis Dictionary Size, Low Byte
|
||||
15 | X X X X X X X X P1 - V42bis Dictionary Size, High Byte
|
||||
16 | X X X X X X X X P2 - V42bis String Length, Low Byte
|
||||
17 | X X X X X X X X P2 - V42bis String Length, High Byte
|
||||
18 | X X X X X X X X PIAFS extension length
|
||||
19 | 1 0 0 0 0 0 0 0 PIAFS extension Id (0x80) - UDATA abilities
|
||||
20 | U 0 0 0 0 0 0 D UDATA abilities -> Note (2)
|
||||
| up to now the following Bits are defined:
|
||||
| D - signal DCD ON
|
||||
| U - use extensive UDATA control communication
|
||||
| for DDI test application
|
||||
+ Note (1): ----------+------+-----------------------------------------+
|
||||
| PIAFS Protocol | Bit | |
|
||||
| Speed configuration | S | Bit 1 - Protocol Speed |
|
||||
| | | 0 - 32K |
|
||||
| | | 1 - 64K (default) |
|
||||
| | V | Bit 2 - Variable Protocol Speed |
|
||||
| | | 0 - Speed is fix |
|
||||
| | | 1 - Speed is variable (default) |
|
||||
| | | OVERWRITES 32k Bit 1 |
|
||||
| | C | Bit 3 0 - Speed Settings according to |
|
||||
| | | PIAFS specification |
|
||||
| | | 1 - Speed setting for chinese |
|
||||
| | | PIAFS implementation |
|
||||
| | | Explanation for chinese speed settings: |
|
||||
| | | if Bit 3 is set the following |
|
||||
| | | rules apply: |
|
||||
| | | Bit1=0 Bit2=0: 32k fix |
|
||||
| | | Bit1=1 Bit2=0: 64k fix |
|
||||
| | | Bit1=0 Bit2=1: PIAFS is trying |
|
||||
| | | to negotiate 32k is that is |
|
||||
| | | not possible it tries to |
|
||||
| | | negotiate 64k |
|
||||
| | | Bit1=1 Bit2=1: PIAFS is trying |
|
||||
| | | to negotiate 64k is that is |
|
||||
| | | not possible it tries to |
|
||||
| | | negotiate 32k |
|
||||
+ Note (2): ----------+------+-----------------------------------------+
|
||||
| PIAFS | Bit | this byte defines the usage of UDATA |
|
||||
| Implementation | | control communication |
|
||||
| UDATA usage | D | Bit 1 - DCD-ON signalling |
|
||||
| | | 0 - no DCD-ON is signalled |
|
||||
| | | (default) |
|
||||
| | | 1 - DCD-ON will be signalled |
|
||||
| | U | Bit 8 - DDI test application UDATA |
|
||||
| | | control communication |
|
||||
| | | 0 - no UDATA control |
|
||||
| | | communication (default) |
|
||||
| | | sets as well the DCD-ON |
|
||||
| | | signalling |
|
||||
| | | 1 - UDATA control communication |
|
||||
| | | ATTENTION: Do not use these |
|
||||
| | | setting if you |
|
||||
| | | are not really |
|
||||
| | | that you need it |
|
||||
| | | and you know |
|
||||
| | | exactly what you |
|
||||
| | | are doing. |
|
||||
| | | You can easily |
|
||||
| | | disable any |
|
||||
| | | data transfer. |
|
||||
+---------------------+------+-----------------------------------------+
|
||||
*/
|
||||
/* ------------------------------------------------------
|
||||
LISTENER DLC DEFINITIONS
|
||||
------------------------------------------------------ */
|
||||
#define LISTENER_FEATURE_MASK_CUMMULATIVE 0x0001
|
||||
/* ------------------------------------------------------
|
||||
LISTENER META-FRAME CODE/PRIMITIVE DEFINITIONS
|
||||
------------------------------------------------------ */
|
||||
#define META_CODE_LL_UDATA_RX 0x01
|
||||
#define META_CODE_LL_UDATA_TX 0x02
|
||||
#define META_CODE_LL_DATA_RX 0x03
|
||||
#define META_CODE_LL_DATA_TX 0x04
|
||||
#define META_CODE_LL_MDATA_RX 0x05
|
||||
#define META_CODE_LL_MDATA_TX 0x06
|
||||
#define META_CODE_EMPTY 0x10
|
||||
#define META_CODE_LOST_FRAMES 0x11
|
||||
#define META_FLAG_TRUNCATED 0x0001
|
||||
/*------------------------------------------------------------------*/
|
||||
/* CAPI-like profile to indicate features on LAW_REQ */
|
||||
/* Please note: ANY ADDITIONS/CHANGES MUST be documented in */
|
||||
/* LEODMS://process_docs/hardware/HWInfoStruct.html */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define GL_INTERNAL_CONTROLLER_SUPPORTED 0x00000001L
|
||||
#define GL_EXTERNAL_EQUIPMENT_SUPPORTED 0x00000002L
|
||||
#define GL_HANDSET_SUPPORTED 0x00000004L
|
||||
#define GL_DTMF_SUPPORTED 0x00000008L
|
||||
#define GL_SUPPLEMENTARY_SERVICES_SUPPORTED 0x00000010L
|
||||
#define GL_CHANNEL_ALLOCATION_SUPPORTED 0x00000020L
|
||||
#define GL_BCHANNEL_OPERATION_SUPPORTED 0x00000040L
|
||||
#define GL_LINE_INTERCONNECT_SUPPORTED 0x00000080L
|
||||
#define GL_BROADBAND_EXTENSIONS_SUPPORTED 0x00000100L
|
||||
#define GL_ECHO_CANCELLER_SUPPORTED 0x00000200L
|
||||
#define B1_HDLC_SUPPORTED 0x00000001L
|
||||
#define B1_TRANSPARENT_SUPPORTED 0x00000002L
|
||||
#define B1_V110_ASYNC_SUPPORTED 0x00000004L
|
||||
#define B1_V110_SYNC_SUPPORTED 0x00000008L
|
||||
#define B1_T30_SUPPORTED 0x00000010L
|
||||
#define B1_HDLC_INVERTED_SUPPORTED 0x00000020L
|
||||
#define B1_TRANSPARENT_R_SUPPORTED 0x00000040L
|
||||
#define B1_MODEM_ALL_NEGOTIATE_SUPPORTED 0x00000080L
|
||||
#define B1_MODEM_ASYNC_SUPPORTED 0x00000100L
|
||||
#define B1_MODEM_SYNC_HDLC_SUPPORTED 0x00000200L
|
||||
#define B2_X75_SUPPORTED 0x00000001L
|
||||
#define B2_TRANSPARENT_SUPPORTED 0x00000002L
|
||||
#define B2_SDLC_SUPPORTED 0x00000004L
|
||||
#define B2_LAPD_SUPPORTED 0x00000008L
|
||||
#define B2_T30_SUPPORTED 0x00000010L
|
||||
#define B2_PPP_SUPPORTED 0x00000020L
|
||||
#define B2_TRANSPARENT_NO_CRC_SUPPORTED 0x00000040L
|
||||
#define B2_MODEM_EC_COMPRESSION_SUPPORTED 0x00000080L
|
||||
#define B2_X75_V42BIS_SUPPORTED 0x00000100L
|
||||
#define B2_V120_ASYNC_SUPPORTED 0x00000200L
|
||||
#define B2_V120_ASYNC_V42BIS_SUPPORTED 0x00000400L
|
||||
#define B2_V120_BIT_TRANSPARENT_SUPPORTED 0x00000800L
|
||||
#define B2_LAPD_FREE_SAPI_SEL_SUPPORTED 0x00001000L
|
||||
#define B3_TRANSPARENT_SUPPORTED 0x00000001L
|
||||
#define B3_T90NL_SUPPORTED 0x00000002L
|
||||
#define B3_ISO8208_SUPPORTED 0x00000004L
|
||||
#define B3_X25_DCE_SUPPORTED 0x00000008L
|
||||
#define B3_T30_SUPPORTED 0x00000010L
|
||||
#define B3_T30_WITH_EXTENSIONS_SUPPORTED 0x00000020L
|
||||
#define B3_RESERVED_SUPPORTED 0x00000040L
|
||||
#define B3_MODEM_SUPPORTED 0x00000080L
|
||||
#define MANUFACTURER_FEATURE_SLAVE_CODEC 0x00000001L
|
||||
#define MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS 0x00000002L
|
||||
#define MANUFACTURER_FEATURE_HARDDTMF 0x00000004L
|
||||
#define MANUFACTURER_FEATURE_SOFTDTMF_SEND 0x00000008L
|
||||
#define MANUFACTURER_FEATURE_DTMF_PARAMETERS 0x00000010L
|
||||
#define MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE 0x00000020L
|
||||
#define MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD 0x00000040L
|
||||
#define MANUFACTURER_FEATURE_V18 0x00000080L
|
||||
#define MANUFACTURER_FEATURE_MIXER_CH_CH 0x00000100L
|
||||
#define MANUFACTURER_FEATURE_MIXER_CH_PC 0x00000200L
|
||||
#define MANUFACTURER_FEATURE_MIXER_PC_CH 0x00000400L
|
||||
#define MANUFACTURER_FEATURE_MIXER_PC_PC 0x00000800L
|
||||
#define MANUFACTURER_FEATURE_ECHO_CANCELLER 0x00001000L
|
||||
#define MANUFACTURER_FEATURE_RTP 0x00002000L
|
||||
#define MANUFACTURER_FEATURE_T38 0x00004000L
|
||||
#define MANUFACTURER_FEATURE_TRANSP_DELIVERY_CONF 0x00008000L
|
||||
#define MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL 0x00010000L
|
||||
#define MANUFACTURER_FEATURE_OOB_CHANNEL 0x00020000L
|
||||
#define MANUFACTURER_FEATURE_IN_BAND_CHANNEL 0x00040000L
|
||||
#define MANUFACTURER_FEATURE_IN_BAND_FEATURE 0x00080000L
|
||||
#define MANUFACTURER_FEATURE_PIAFS 0x00100000L
|
||||
#define MANUFACTURER_FEATURE_DTMF_TONE 0x00200000L
|
||||
#define MANUFACTURER_FEATURE_FAX_PAPER_FORMATS 0x00400000L
|
||||
#define MANUFACTURER_FEATURE_OK_FC_LABEL 0x00800000L
|
||||
#define MANUFACTURER_FEATURE_VOWN 0x01000000L
|
||||
#define MANUFACTURER_FEATURE_XCONNECT 0x02000000L
|
||||
#define MANUFACTURER_FEATURE_DMACONNECT 0x04000000L
|
||||
#define MANUFACTURER_FEATURE_AUDIO_TAP 0x08000000L
|
||||
#define MANUFACTURER_FEATURE_FAX_NONSTANDARD 0x10000000L
|
||||
#define MANUFACTURER_FEATURE_SS7 0x20000000L
|
||||
#define MANUFACTURER_FEATURE_MADAPTER 0x40000000L
|
||||
#define MANUFACTURER_FEATURE_MEASURE 0x80000000L
|
||||
#define MANUFACTURER_FEATURE2_LISTENING 0x00000001L
|
||||
#define MANUFACTURER_FEATURE2_SS_DIFFCONTPOSSIBLE 0x00000002L
|
||||
#define MANUFACTURER_FEATURE2_GENERIC_TONE 0x00000004L
|
||||
#define MANUFACTURER_FEATURE2_COLOR_FAX 0x00000008L
|
||||
#define MANUFACTURER_FEATURE2_SS_ECT_DIFFCONTPOSSIBLE 0x00000010L
|
||||
#define MANUFACTURER_FEATURE2_TRANSPARENT_N_RESET 0x00000020L
|
||||
/*
|
||||
Following four bits are reserved for vendor specific extensions
|
||||
Vendor specific extension allows values from 0x01 to 0x0e
|
||||
*/
|
||||
#define MANUFACTURER_FEATURE2_VENDOR_MASK_FIRST_BIT 6 /* 0x00000040L */
|
||||
#define MANUFACTURER_FEATURE2_VENDOR_BITS 0x0000000fL
|
||||
#define MANUFACTURER_FEATURE2_VENDOR_MASK \
|
||||
(MANUFACTURER_FEATURE2_VENDOR_BITS << MANUFACTURER_FEATURE2_VENDOR_MASK_FIRST_BIT)
|
||||
#define MANUFACTURER_FEATURE2_CAPTARIS_ADAPTER \
|
||||
(0x00000001L << MANUFACTURER_FEATURE2_VENDOR_MASK_FIRST_BIT)
|
||||
#define MANUFACTURER_FEATURE2_DIALING_CHARS_ACCEPTED 0x00000400L
|
||||
#define MANUFACTURER_FEATURE2_NULL_PLCI 0x00000800L
|
||||
#define MANUFACTURER_FEATURE2_X25_REVERSE_RESTART 0x00001000L
|
||||
#define MANUFACTURER_FEATURE2_SOFTIP 0x00002000L
|
||||
#define MANUFACTURER_FEATURE2_CLEAR_CHANNEL 0x00004000L
|
||||
#define MANUFACTURER_FEATURE2_LINE_SIDE_T38 0x00008000L
|
||||
#define MANUFACTURER_FEATURE2_RTP_LINE 0x00010000L
|
||||
#define MANUFACTURER_FEATURE2_NO_CLOCK_LINE 0x00020000L
|
||||
#define MANUFACTURER_FEATURE2_TRANSCODING 0x00040000L
|
||||
#define MANUFACTURER_FEATURE2_MODEM_V34_V90 0x00080000L
|
||||
#define MANUFACTURER_FEATURE2_PLUGIN_MODULATION 0x00100000L
|
||||
#define MANUFACTURER_FEATURE2_FAX_V34 0x00200000L
|
||||
#define MANUFACTURER_FEATURE2_MODEM_V34_LOW 0x00400000L
|
||||
#define MANUFACTURER_FEATURE2_STREAMING_IDI 0x00800000L
|
||||
#define RTP_PRIM_PAYLOAD_PCMU_8000 0
|
||||
#define RTP_PRIM_PAYLOAD_1016_8000 1
|
||||
#define RTP_PRIM_PAYLOAD_LINEAR16_8000 1
|
||||
#define RTP_PRIM_PAYLOAD_G726_32_8000 2
|
||||
#define RTP_PRIM_PAYLOAD_GSM_8000 3
|
||||
#define RTP_PRIM_PAYLOAD_G723_8000 4
|
||||
#define RTP_PRIM_PAYLOAD_DVI4_8000 5
|
||||
#define RTP_PRIM_PAYLOAD_DVI4_16000 6
|
||||
#define RTP_PRIM_PAYLOAD_LPC_8000 7
|
||||
#define RTP_PRIM_PAYLOAD_PCMA_8000 8
|
||||
#define RTP_PRIM_PAYLOAD_G722_16000 9
|
||||
#define RTP_PRIM_PAYLOAD_QCELP_8000 12
|
||||
#define RTP_PRIM_PAYLOAD_G728_8000 14
|
||||
#define RTP_PRIM_PAYLOAD_G729_8000 18
|
||||
#define RTP_PRIM_PAYLOAD_RTAUDIO_8000 26
|
||||
#define RTP_PRIM_PAYLOAD_ILBC_8000 27
|
||||
#define RTP_PRIM_PAYLOAD_AMR_NB_8000 28
|
||||
#define RTP_PRIM_PAYLOAD_T38 29
|
||||
#define RTP_PRIM_PAYLOAD_GSM_HR_8000 30
|
||||
#define RTP_PRIM_PAYLOAD_GSM_EFR_8000 31
|
||||
#define RTP_ADD_PAYLOAD_BASE 32
|
||||
#define RTP_ADD_PAYLOAD_RED 32
|
||||
#define RTP_ADD_PAYLOAD_CN_8000 33
|
||||
#define RTP_ADD_PAYLOAD_DTMF 34
|
||||
#define RTP_ADD_PAYLOAD_FEC 35
|
||||
#define RTP_PRIM_PAYLOAD_PCMU_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_PCMU_8000)
|
||||
#define RTP_PRIM_PAYLOAD_1016_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_1016_8000)
|
||||
#define RTP_PRIM_PAYLOAD_LINEAR16_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_LINEAR16_8000)
|
||||
#define RTP_PRIM_PAYLOAD_G726_32_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G726_32_8000)
|
||||
#define RTP_PRIM_PAYLOAD_GSM_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_8000)
|
||||
#define RTP_PRIM_PAYLOAD_G723_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G723_8000)
|
||||
#define RTP_PRIM_PAYLOAD_DVI4_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_DVI4_8000)
|
||||
#define RTP_PRIM_PAYLOAD_DVI4_16000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_DVI4_16000)
|
||||
#define RTP_PRIM_PAYLOAD_LPC_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_LPC_8000)
|
||||
#define RTP_PRIM_PAYLOAD_PCMA_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_PCMA_8000)
|
||||
#define RTP_PRIM_PAYLOAD_G722_16000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G722_16000)
|
||||
#define RTP_PRIM_PAYLOAD_QCELP_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_QCELP_8000)
|
||||
#define RTP_PRIM_PAYLOAD_G728_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G728_8000)
|
||||
#define RTP_PRIM_PAYLOAD_G729_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_G729_8000)
|
||||
#define RTP_PRIM_PAYLOAD_RTAUDIO_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_RTAUDIO_8000)
|
||||
#define RTP_PRIM_PAYLOAD_ILBC_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_ILBC_8000)
|
||||
#define RTP_PRIM_PAYLOAD_AMR_NB_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_AMR_NB_8000)
|
||||
#define RTP_PRIM_PAYLOAD_T38_SUPPORTED (1L << RTP_PRIM_PAYLOAD_T38)
|
||||
#define RTP_PRIM_PAYLOAD_GSM_HR_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_HR_8000)
|
||||
#define RTP_PRIM_PAYLOAD_GSM_EFR_8000_SUPPORTED (1L << RTP_PRIM_PAYLOAD_GSM_EFR_8000)
|
||||
#define RTP_ADD_PAYLOAD_RED_SUPPORTED (1L << (RTP_ADD_PAYLOAD_RED - RTP_ADD_PAYLOAD_BASE))
|
||||
#define RTP_ADD_PAYLOAD_CN_8000_SUPPORTED (1L << (RTP_ADD_PAYLOAD_CN_8000 - RTP_ADD_PAYLOAD_BASE))
|
||||
#define RTP_ADD_PAYLOAD_DTMF_SUPPORTED (1L << (RTP_ADD_PAYLOAD_DTMF - RTP_ADD_PAYLOAD_BASE))
|
||||
#define RTP_ADD_PAYLOAD_FEC_SUPPORTED (1L << (RTP_ADD_PAYLOAD_FEC - RTP_ADD_PAYLOAD_BASE))
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Definitions to indicate Layer 1/2/3 status on STATUS_REQ */
|
||||
/*------------------------------------------------------------------*/
|
||||
#define CST_STATE_LAYER_MASK 0xe000
|
||||
#define CST_STATE_UP_BIT 0x1000
|
||||
#define CST_STATE_UP_INSTANCES_MASK 0x0fff
|
||||
#define CST_STATE_PROTOCOL_MASK 0xe03f
|
||||
#define CST_STATE_LEVEL_MASK 0x0fc0
|
||||
#define CST_STATE_LAYER_D_L1 0x0000
|
||||
#define CST_STATE_LAYER_D_L2 0x2000
|
||||
#define CST_STATE_LAYER_D_L3 0x4000
|
||||
#define CST_STATE_LAYER_B_L1 0x8000
|
||||
#define CST_STATE_LAYER_B_L2 0xa000
|
||||
#define CST_STATE_LAYER_B_L3 0xc000
|
||||
#define CST_STATE_I430(level) (CST_STATE_LAYER_D_L1 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_I431(level) (CST_STATE_LAYER_D_L1 | 0x01 | ((level) << 6))
|
||||
#define CST_STATE_Q921(level) (CST_STATE_LAYER_D_L2 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_Q931(level) (CST_STATE_LAYER_D_L3 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_CAS(level) (CST_STATE_LAYER_D_L3 | 0x01 | ((level) << 6))
|
||||
#define CST_STATE_HDLC(level) (CST_STATE_LAYER_B_L1 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_V110(level) (CST_STATE_LAYER_B_L1 | 0x01 | ((level) << 6))
|
||||
#define CST_STATE_X75(level) (CST_STATE_LAYER_B_L2 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_X25(level) (CST_STATE_LAYER_B_L3 | 0x00 | ((level) << 6))
|
||||
#define CST_STATE_I430_INACTIVE (CST_STATE_I430(0x00)) /* ITU-T I.430: F1 */
|
||||
#define CST_STATE_I430_TE_SENSING (CST_STATE_I430(0x04)) /* ITU-T I.430: F2 */
|
||||
#define CST_STATE_I430_TE_SENSING_LOW_POWER (CST_STATE_I430(0x05)) /* ITU-T I.430: F2, low power mode */
|
||||
#define CST_STATE_I430_DEACTIVATED (CST_STATE_I430(0x08)) /* ITU-T I.430: F3/G1 */
|
||||
#define CST_STATE_I430_DEACTIVATED_LOW_POWER (CST_STATE_I430(0x09)) /* ITU-T I.430: F3/G1, low power mode */
|
||||
#define CST_STATE_I430_TE_AWAITING_SIGNAL (CST_STATE_I430(0x10)) /* ITU-T I.430: F4 */
|
||||
#define CST_STATE_I430_NT_PENDING_ACTIVATION (CST_STATE_I430(0x11)) /* ITU-T I.430: G2 */
|
||||
#define CST_STATE_I430_TE_IDENTIFYING_INPUT (CST_STATE_I430(0x20)) /* ITU-T I.430: F5 */
|
||||
#define CST_STATE_I430_TE_SYNCHRONIZED (CST_STATE_I430(0x22)) /* ITU-T I.430: F6 */
|
||||
#define CST_STATE_I430_ACTIVATED (CST_STATE_LAYER_D_L1 | CST_STATE_UP_BIT) /* ITU-T I.430: F7/G3 */
|
||||
#define CST_STATE_I430_NT_PENDING_DEACTIVATION (CST_STATE_I430(0x1f)) /* ITU-T I.430: G4 */
|
||||
#define CST_STATE_I430_TE_LOSS_OF_FRAMING (CST_STATE_I430(0x21)) /* ITU-T I.430: F8 */
|
||||
#define CST_STATE_I431_INACTIVE (CST_STATE_I431(0x00)) /* ITU-T I.431: F0/G0 */
|
||||
#define CST_STATE_I431_OPERATIONAL (CST_STATE_LAYER_D_L1 | CST_STATE_UP_BIT) /* ITU-T I.431: F1/G1 */
|
||||
#define CST_STATE_I431_REMOTE_ALARM (CST_STATE_I431(0x26)) /* ITU-T I.431: F2/G2, FC1, yellow alarm */
|
||||
#define CST_STATE_I431_LOSS_OF_SIGNAL (CST_STATE_I431(0x14)) /* ITU-T I.431: F3/G3, FC2, red alarm */
|
||||
#define CST_STATE_I431_LOSS_OF_FRAMING (CST_STATE_I431(0x24)) /* ITU-T I.431: F4/G4, FC3, blue alarm */
|
||||
#define CST_STATE_I431_REMOTE_ALARM_CRC_ERR (CST_STATE_I431(0x25)) /* ITU-T I.431: F5/G5, FC4, yellow alarm, CRC errors */
|
||||
#define CST_STATE_I431_POWER_ON (CST_STATE_I431(0x01)) /* ITU-T I.431: F6/G6 */
|
||||
#define CST_STATE_I431_LOSS_OF_DOUBLEFRAMING (CST_STATE_I431(0x27)) /* */
|
||||
#define CST_STATE_I431_LOSS_OF_MULTIFRAMING (CST_STATE_I431(0x28)) /* */
|
||||
#define CST_STATE_I431_TS16_LOSS_OF_SIGNAL (CST_STATE_I431(0x2e)) /* All zeroes in timeslot 16 */
|
||||
#define CST_STATE_I431_TS16_REMOTE_ALARM (CST_STATE_I431(0x36)) /* Remote alarm bit RS1.2 set in timeslot 16 */
|
||||
#define CST_STATE_I431_TS16_ALARM_INDICATION (CST_STATE_I431(0x30)) /* Less than 4 zeroes in 2 consecutive multiframes */
|
||||
#define CST_STATE_I431_TS16_LOSS_OF_MULTIFRAMING (CST_STATE_I431(0x38)) /* CAS framing pattern lost */
|
||||
#define CST_STATE_I431_EXCESSIVE_ZEROES_DETECTED (CST_STATE_I431(0x1e)) /* More than 3 (HDB3) or 15 (AMI) consecutive zeroes */
|
||||
#define CST_STATE_I431_TRANSMIT_LINE_SHORT (CST_STATE_I431(0x0d)) /* */
|
||||
#define CST_STATE_I431_TRANSMIT_LINE_OPEN (CST_STATE_I431(0x0e)) /* */
|
||||
#define CST_STATE_Q921_TEI_UNASSIGNED (CST_STATE_Q921(0x00)) /* ITU-T Q.921: 4.3 State 1/B.2 State 1 */
|
||||
#define CST_STATE_Q921_ASSIGN_AWAITING_TEI (CST_STATE_Q921(0x08)) /* ITU-T Q.921: B.2 State 2 */
|
||||
#define CST_STATE_Q921_ESTABLISH_AWAITING_TEI (CST_STATE_Q921(0x09)) /* ITU-T Q.921: B.2 State 3 */
|
||||
#define CST_STATE_Q921_TEI_ASSIGNED (CST_STATE_Q921(0x10)) /* ITU-T Q.921: B.2 State 4 */
|
||||
#define CST_STATE_Q921_AWAITING_ESTABLISHMENT (CST_STATE_Q921(0x20)) /* ITU-T Q.921: 4.3 State 2/B.2 State 5 */
|
||||
#define CST_STATE_Q921_AWAITING_RELEASE (CST_STATE_Q921(0x3f)) /* ITU-T Q.921: 4.3 State 3/B.2 State 6 */
|
||||
#define CST_STATE_Q921_MULTIPLE_FRAME_ESTABLISHED (CST_STATE_LAYER_D_L2 | CST_STATE_UP_BIT) /* ITU-T Q.921: 4.3 State 4/B.2 State 7 */
|
||||
#define CST_STATE_Q921_TIMER_RECOVERY (CST_STATE_Q921(0x21)) /* ITU-T Q.921: B.2 State 8 */
|
||||
#define CST_STATE_Q931_NULL (CST_STATE_Q931(0x00)) /* ITU-T Q.931: U0/N0 */
|
||||
#define CST_STATE_Q931_CALL_INITIATED (CST_STATE_Q931(0x01)) /* ITU-T Q.931: U1/N1 */
|
||||
#define CST_STATE_Q931_OVERLAP_SENDING (CST_STATE_Q931(0x02)) /* ITU-T Q.931: U2/N2 */
|
||||
#define CST_STATE_Q931_OUTGOING_CALL_PROCEEDING (CST_STATE_Q931(0x03)) /* ITU-T Q.931: U3/N3 */
|
||||
#define CST_STATE_Q931_CALL_DELIVERED (CST_STATE_Q931(0x04)) /* ITU-T Q.931: U4/N4 */
|
||||
#define CST_STATE_Q931_CALL_PRESENT (CST_STATE_Q931(0x06)) /* ITU-T Q.931: U6/N6 */
|
||||
#define CST_STATE_Q931_CALL_RECEIVED (CST_STATE_Q931(0x07)) /* ITU-T Q.931: U7/N7 */
|
||||
#define CST_STATE_Q931_CONNECT_REQUEST (CST_STATE_Q931(0x08)) /* ITU-T Q.931: U8/N8 */
|
||||
#define CST_STATE_Q931_INCOMING_CALL_PROCEEDING (CST_STATE_Q931(0x09)) /* ITU-T Q.931: U9/N9 */
|
||||
#define CST_STATE_Q931_ACTIVE (CST_STATE_LAYER_D_L3 | CST_STATE_UP_BIT) /* ITU-T Q.931: U10/N10 */
|
||||
#define CST_STATE_Q931_DISCONNECT_REQUEST (CST_STATE_Q931(0x0b)) /* ITU-T Q.931: U11/N11 */
|
||||
#define CST_STATE_Q931_DISCONNECT_INDICATION (CST_STATE_Q931(0x0c)) /* ITU-T Q.931: U12/N12 */
|
||||
#define CST_STATE_Q931_SUSPEND_REQUEST (CST_STATE_Q931(0x0f)) /* ITU-T Q.931: U15/N15 */
|
||||
#define CST_STATE_Q931_RESUME_REQUEST (CST_STATE_Q931(0x11)) /* ITU-T Q.931: U17/N17 */
|
||||
#define CST_STATE_Q931_RELEASE_REQUEST (CST_STATE_Q931(0x13)) /* ITU-T Q.931: U19/N19 */
|
||||
#define CST_STATE_Q931_CALL_ABORT (CST_STATE_Q931(0x16)) /* ITU-T Q.931: N22 */
|
||||
#define CST_STATE_Q931_OVERLAP_RECEIVING (CST_STATE_Q931(0x19)) /* ITU-T Q.931: U25/N25 */
|
||||
#define CST_STATE_CAS_NULL (CST_STATE_CAS(0x00)) /* like ITU-T Q.931: U0/N0 */
|
||||
#define CST_STATE_CAS_CALL_INITIATED (CST_STATE_CAS(0x01)) /* like ITU-T Q.931: U1/N1 */
|
||||
#define CST_STATE_CAS_OVERLAP_SENDING (CST_STATE_CAS(0x02)) /* like ITU-T Q.931: U2/N2 */
|
||||
#define CST_STATE_CAS_OUTGOING_CALL_PROCEEDING (CST_STATE_CAS(0x03)) /* like ITU-T Q.931: U3/N3 */
|
||||
#define CST_STATE_CAS_CALL_DELIVERED (CST_STATE_CAS(0x04)) /* like ITU-T Q.931: U4/N4 */
|
||||
#define CST_STATE_CAS_CALL_PRESENT (CST_STATE_CAS(0x06)) /* like ITU-T Q.931: U6/N6 */
|
||||
#define CST_STATE_CAS_CALL_RECEIVED (CST_STATE_CAS(0x07)) /* like ITU-T Q.931: U7/N7 */
|
||||
#define CST_STATE_CAS_CONNECT_REQUEST (CST_STATE_CAS(0x08)) /* like ITU-T Q.931: U8/N8 */
|
||||
#define CST_STATE_CAS_INCOMING_CALL_PROCEEDING (CST_STATE_CAS(0x09)) /* like ITU-T Q.931: U9/N9 */
|
||||
#define CST_STATE_CAS_ACTIVE (CST_STATE_LAYER_D_L3 | CST_STATE_UP_BIT) /* like ITU-T Q.931: U10/N10 */
|
||||
#define CST_STATE_CAS_DISCONNECT_REQUEST (CST_STATE_CAS(0x0b)) /* like ITU-T Q.931: U11/N11 */
|
||||
#define CST_STATE_CAS_DISCONNECT_INDICATION (CST_STATE_CAS(0x0c)) /* like ITU-T Q.931: U12/N12 */
|
||||
#define CST_STATE_CAS_SUSPEND_REQUEST (CST_STATE_CAS(0x0f)) /* like ITU-T Q.931: U15/N15 */
|
||||
#define CST_STATE_CAS_RESUME_REQUEST (CST_STATE_CAS(0x11)) /* like ITU-T Q.931: U17/N17 */
|
||||
#define CST_STATE_CAS_RELEASE_REQUEST (CST_STATE_CAS(0x13)) /* like ITU-T Q.931: U19/N19 */
|
||||
#define CST_STATE_CAS_CALL_ABORT (CST_STATE_CAS(0x16)) /* like ITU-T Q.931: N22 */
|
||||
#define CST_STATE_CAS_OVERLAP_RECEIVING (CST_STATE_CAS(0x19)) /* like ITU-T Q.931: U25/N25 */
|
||||
#define CST_STATE_CAS_LINE_IN_USE (CST_STATE_CAS(0x3b)) /* */
|
||||
#define CST_STATE_CAS_LOCAL_REMOTE_BLOCKING (CST_STATE_CAS(0x3c)) /* */
|
||||
#define CST_STATE_CAS_LOCAL_BLOCKING (CST_STATE_CAS(0x3d)) /* */
|
||||
#define CST_STATE_CAS_REMOTE_BLOCKING (CST_STATE_CAS(0x3e)) /* */
|
||||
#define CST_STATE_X75_IDLE (CST_STATE_X75(0x00)) /* */
|
||||
#define CST_STATE_X75_AWAITING_ESTABLISHMENT (CST_STATE_X75(0x20)) /* */
|
||||
#define CST_STATE_X75_AWAITING_RELEASE (CST_STATE_X75(0x3f)) /* */
|
||||
#define CST_STATE_X75_ESTABLISHED (CST_STATE_LAYER_B_L2 | CST_STATE_UP_BIT) /* */
|
||||
#define CST_STATE_X25_PACKET_LAYER_READY (CST_STATE_X25(0x01)) /* ITU-T X.25: r1 */
|
||||
#define CST_STATE_X25_DTE_RESTART_REQUEST (CST_STATE_X25(0x02)) /* ITU-T X.25: r2 */
|
||||
#define CST_STATE_X25_DCE_RESTART_INDICATION (CST_STATE_X25(0x03)) /* ITU-T X.25: r3 */
|
||||
#define CST_STATE_X25_READY (CST_STATE_X25(0x04)) /* ITU-T X.25: p1 */
|
||||
#define CST_STATE_X25_DTE_WAITING (CST_STATE_X25(0x05)) /* ITU-T X.25: p2 */
|
||||
#define CST_STATE_X25_DCE_WAITING (CST_STATE_X25(0x06)) /* ITU-T X.25: p3 */
|
||||
#define CST_STATE_X25_DATA_TRANSFER (CST_STATE_LAYER_B_L3 | CST_STATE_UP_BIT) /* ITU-T X.25: p4 */
|
||||
#define CST_STATE_X25_CALL_COLLISION (CST_STATE_X25(0x08)) /* ITU-T X.25: p5 */
|
||||
#define CST_STATE_X25_DTE_CLEAR_REQUEST (CST_STATE_X25(0x09)) /* ITU-T X.25: p6 */
|
||||
#define CST_STATE_X25_DCE_CLEAR_INDICATION (CST_STATE_X25(0x0a)) /* ITU-T X.25: p7 */
|
||||
#define CST_STATE_X25_FLOW_CONTROL_READY (CST_STATE_X25(0x0b)) /* ITU-T X.25: d1 */
|
||||
#define CST_STATE_X25_DTE_RESET_REQUEST (CST_STATE_X25(0x0c)) /* ITU-T X.25: d2 */
|
||||
#define CST_STATE_X25_DCE_RESET_REQUEST (CST_STATE_X25(0x0d)) /* ITU-T X.25: d3 */
|
||||
/*------------------------------------------------------------------*/
|
||||
/* virtual switching definitions */
|
||||
#define VSJOIN 1
|
||||
#define VSTRANSPORT 2
|
||||
#define VSGETPARAMS 3
|
||||
#define VSCAD 1
|
||||
#define VSRXCPNAME 2
|
||||
#define VSCALLSTAT 3
|
||||
#define VSINVOKEID 4
|
||||
#define VSCLMRKS 5
|
||||
#define VSTBCTIDENT 6
|
||||
#define VSETSILINKID 7
|
||||
#define VSSAMECONTROLLER 8
|
||||
#define VSCTBYREROUTEID 9
|
||||
/* Errorcodes for VSLINKID begin */
|
||||
#define VSLINKIDRRWC 1
|
||||
#define VSLINKIDREJECT 2
|
||||
#define VSLINKIDTIMEOUT 3
|
||||
#define VSLINKIDFAILCOUNT 4
|
||||
#define VSLINKIDERROR 5
|
||||
/* Errorcodes for VSLINKID end */
|
||||
/* -----------------------------------------------------------**
|
||||
** The PROTOCOL_FEATURE_STRING in feature.h (included **
|
||||
** in prstart.sx and astart.sx) defines capabilities and **
|
||||
** features of the actual protocol code. It's used as a bit **
|
||||
** mask. **
|
||||
** The following Bits are defined: **
|
||||
** -----------------------------------------------------------*/
|
||||
#define PROTCAP_TELINDUS 0x0001 /* Telindus Variant of protocol code */
|
||||
#define PROTCAP_MAN_IF 0x0002 /* Management interface implemented */
|
||||
#define PROTCAP_V_42 0x0004 /* V42 implemented */
|
||||
#define PROTCAP_V90D 0x0008 /* V.90D (implies up to 384k DSP code) */
|
||||
#define PROTCAP_EXTD_FAX 0x0010 /* Extended FAX (ECM, 2D, T6, Polling) */
|
||||
#define PROTCAP_EXTD_RXFC 0x0020 /* RxFC (Extd Flow Control), OOB Chnl */
|
||||
#define PROTCAP_VOIP 0x0040 /* VoIP (implies up to 512k DSP code) */
|
||||
#define PROTCAP_CMA_ALLPR 0x0080 /* CMA support for all NL primitives */
|
||||
#define PROTCAP_64BIT_DMA 0x0100 /* 64 Bit addresses on PCI BUS DMA */
|
||||
#define PROTCAP_FREE9 0x0200 /* not used */
|
||||
#define PROTCAP_FREE10 0x0400 /* not used */
|
||||
#define PROTCAP_FREE11 0x0800 /* not used */
|
||||
#define PROTCAP_FREE12 0x1000 /* not used */
|
||||
#define PROTCAP_FREE13 0x2000 /* not used */
|
||||
#define PROTCAP_FREE14 0x4000 /* not used */
|
||||
#define PROTCAP_EXTENSION 0x8000 /* used for future extentions */
|
||||
/* -----------------------------------------------------------* */
|
||||
/* Onhook data transmission ETS30065901 */
|
||||
/* Message Type */
|
||||
#define CALLING_NUMBER_DELIVERY 0x04
|
||||
#define CALL_SETUP 0x80
|
||||
#define MESSAGE_WAITING_INDICATOR 0x82
|
||||
/*#define RESERVED84 0x84*/
|
||||
/*#define RESERVED85 0x85*/
|
||||
#define ADVICE_OF_CHARGE 0x86
|
||||
/*1111 0001
|
||||
to
|
||||
1111 1111
|
||||
F1H - Reserved for network operator use
|
||||
to
|
||||
FFH*/
|
||||
/* Parameter Types */
|
||||
#define DATE_AND_TIME 1
|
||||
#define CLI_PARAMETER_TYPE 2
|
||||
#define CALLED_DIRECTORY_NUMBER_PARAMETER_TYPE 3
|
||||
#define REASON_FOR_ABSENCE_OF_CLI_PARAMETER_TYPE 4
|
||||
#define CALL_QUALIFIER 6
|
||||
#define NAME_PARAMETER_TYPE 7
|
||||
#define REASON_FOR_ABSENCE_OF_CALLING_PARTY_NAME_PARAMETER_TYPE 8
|
||||
#define VISUAL_INDICATOR_PARAMETER_TYPE 0xb
|
||||
#define COMPLEMENTARY_CLI_PARAMETER_TYPE 0x10
|
||||
#define CALL_TYPE_PARAMETER_TYPE 0x11
|
||||
#define FIRST_CALLED_LINE_DIRECTORY_NUMBER_PARAMETER_TYPE 0x12
|
||||
#define NETWORK_MESSAGE_SYSTEM_STATUS_PARAMETER_TYPE 0x13
|
||||
#define FORWARDED_CALL_TYPE_PARAMETER_TYPE 0x15
|
||||
#define TYPE_OF_CALLING_USER_PARAMETER_TYPE 0x16
|
||||
#define REDIRECTING_NUMBER_PARAMETER_TYPE 0x1a
|
||||
#define EXTENSION_FOR_NETWORK_OPERATOR_USE_PARAMETER_TYPE 0xe0
|
||||
/* -----------------------------------------------------------* */
|
||||
#else
|
||||
#endif /* PC_H_INCLUDED } */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_OS_STREAMING_PLATFORM_H__
|
||||
#define __DIVA_OS_STREAMING_PLATFORM_H__
|
||||
|
||||
#define DIVA_USERMODE 1
|
||||
#define LINUX 1
|
||||
|
||||
#if !defined(__i386__)
|
||||
#define READ_WORD(w) ( ((byte *)(w))[0] + \
|
||||
(((byte *)(w))[1]<<8) )
|
||||
|
||||
#define READ_DWORD(w) ( ((byte *)(w))[0] + \
|
||||
(((byte *)(w))[1]<<8) + \
|
||||
(((byte *)(w))[2]<<16) + \
|
||||
(((byte *)(w))[3]<<24) )
|
||||
|
||||
#define WRITE_WORD(b,w) do{ ((byte*)(b))[0]=(byte)(w); \
|
||||
((byte*)(b))[1]=(byte)((w)>>8); }while(0)
|
||||
|
||||
#define WRITE_DWORD(b,w) do{ ((byte*)(b))[0]=(byte)(w); \
|
||||
((byte*)(b))[1]=(byte)((w)>>8); \
|
||||
((byte*)(b))[2]=(byte)((w)>>16); \
|
||||
((byte*)(b))[3]=(byte)((w)>>24); }while(0)
|
||||
#else
|
||||
#define READ_WORD(w) (*(word *)(w))
|
||||
#define READ_DWORD(w) (*(dword *)(w))
|
||||
#define WRITE_WORD(b,w) do{ *(word *)(b)=(w); }while(0)
|
||||
#define WRITE_DWORD(b,w) do{ *(dword *)(b)=(w); }while(0)
|
||||
#endif
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int dword;
|
||||
typedef signed int int32;
|
||||
typedef unsigned long long qword;
|
||||
|
||||
#ifndef likely
|
||||
#define likely(__x__) (!!(__x__))
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(__x__) (!!(__x__))
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a)>(b) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define DIVAS_CONTAINING_RECORD(address, type, field) \
|
||||
((type *)((char*)(address) - (char*)(&((type *)0)->field)))
|
||||
|
||||
#define DIVA_STREAMING_MAX_TRACE_IDENT_LENGTH 4
|
||||
|
||||
void* diva_os_malloc (unsigned long flags, unsigned long size);
|
||||
void diva_os_free (unsigned long flags, void* ptr);
|
||||
|
||||
#define _DI_STREAM_CTRL 0x0014
|
||||
|
||||
#include <string.h>
|
||||
#include "debuglib.h"
|
||||
|
||||
#define DIVA_SHARED_SEGMENT_ALLOC 1
|
||||
/*
|
||||
DIVA_SHARED_SEGMENT_LOCK used to lock shared segment alloc instance. Locked instance is newer freed
|
||||
due to reference counter newer receives zero. This allows to maintain permenently mapped pool of pages
|
||||
and to reduce overall system load.
|
||||
Causes memory load if application is stopped, but memory and mapped resources are freed by OS.
|
||||
*/
|
||||
#define DIVA_SHARED_SEGMENT_LOCK 1
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2011
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "platform.h"
|
||||
#include <malloc.h>
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_utils.h"
|
||||
|
||||
void* diva_os_malloc (unsigned long flags, unsigned long size) {
|
||||
void* ret = 0;
|
||||
|
||||
if (size != 0) {
|
||||
ret = ast_malloc (size);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void diva_os_free (unsigned long flags, void* ptr) {
|
||||
if (ptr != 0) {
|
||||
ast_free (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void diva_runtime_error_message (const char* fmt, ...) {
|
||||
char tmp[512];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(tmp, sizeof(tmp), fmt, ap);
|
||||
va_end(ap);
|
||||
tmp[sizeof(tmp)-1]=0;
|
||||
|
||||
cc_log(LOG_ERROR, "%s\n", tmp);
|
||||
}
|
||||
|
||||
void diva_runtime_log_message (const char* fmt, ...) {
|
||||
char tmp[512];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(tmp, sizeof(tmp), fmt, ap);
|
||||
va_end(ap);
|
||||
tmp[sizeof(tmp)-1]=0;
|
||||
|
||||
cc_verbose(4, 0, "%s\n", tmp);
|
||||
}
|
||||
|
||||
void diva_runtime_trace_message (const char* fmt, ...) {
|
||||
char tmp[512];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(tmp, sizeof(tmp), fmt, ap);
|
||||
va_end(ap);
|
||||
tmp[sizeof(tmp)-1]=0;
|
||||
|
||||
cc_verbose(4, 1, "%s\n", tmp);
|
||||
}
|
||||
|
||||
void diva_runtime_binary_message (const void* data, unsigned long data_length) {
|
||||
static const char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
word i, j;
|
||||
char *p;
|
||||
char hex_line[50];
|
||||
const byte *buffer = data;
|
||||
word length = (word)data_length;
|
||||
|
||||
for (i = 0; i < length; i += 16) {
|
||||
p = hex_line;
|
||||
for (j = 0; (j < 16) && (i+j < length); j++) {
|
||||
*(p++) = ' ';
|
||||
*(p++) = hex_digit_table[buffer[i+j] >> 4];
|
||||
*(p++) = hex_digit_table[buffer[i+j] & 0xf];
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
cc_verbose(4, 1, "[%02x]%s\n", (unsigned int) i, hex_line);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* vim:ts=2:
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "dlist.h"
|
||||
#include "diva_segment_alloc_ifc.h"
|
||||
#ifdef DIVA_USERMODE
|
||||
#include "xdi_msg.h"
|
||||
#else
|
||||
#include "pc.h"
|
||||
#include "di_defs.h"
|
||||
#include "divasync.h"
|
||||
#endif
|
||||
#include "debuglib.h"
|
||||
|
||||
#if defined(LINUX) && defined(DIVA_USERMODE)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
typedef struct _diva_map_entry {
|
||||
diva_entity_link_t link;
|
||||
int entry_nr;
|
||||
dword dma_lo;
|
||||
dword dma_hi;
|
||||
void* mem;
|
||||
} diva_map_entry_t;
|
||||
|
||||
typedef struct _diva_segment_alloc {
|
||||
diva_segment_alloc_access_t ifc;
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
int fd;
|
||||
int fd_mem;
|
||||
int fd_xdi;
|
||||
#endif
|
||||
#else
|
||||
DESCRIPTOR* d;
|
||||
#endif
|
||||
diva_entity_queue_t free_q;
|
||||
diva_entity_queue_t busy_q;
|
||||
#if !defined(DIVA_USERMODE)
|
||||
IDI_SYNC_REQ syncReq;
|
||||
#endif
|
||||
} diva_segment_alloc_t;
|
||||
|
||||
/*
|
||||
* LOCALS
|
||||
*/
|
||||
static void release_proc(struct _diva_segment_alloc**);
|
||||
static void* segment_alloc_proc(struct _diva_segment_alloc*, dword* lo, dword* hi);
|
||||
static void segment_free_proc(struct _diva_segment_alloc*, void* addr, dword lo, dword hi);
|
||||
static dword get_segment_length_proc(struct _diva_segment_alloc*);
|
||||
#if defined(DIVA_USERMODE)
|
||||
static int map_entry (struct _diva_segment_alloc* pI, diva_map_entry_t* pE);
|
||||
#endif
|
||||
static void* map_address (struct _diva_segment_alloc* ifc, dword lo, dword hi, int map_host);
|
||||
static void* umap_address (struct _diva_segment_alloc* ifc, dword lo, dword hi, void* local);
|
||||
static int write_address (struct _diva_segment_alloc* ifc, dword lo, dword hi, dword data);
|
||||
static void resource_removed (struct _diva_segment_alloc* ifc);
|
||||
|
||||
#if !defined(DIVA_USERMODE)
|
||||
static void diva_segment_allloc_resource_removed_request(ENTITY* e) { }
|
||||
static DESCRIPTOR diva_segment_alloc_resource_removed_descriptor =
|
||||
{ 0, 0, 0, diva_segment_allloc_resource_removed_request };
|
||||
#endif
|
||||
|
||||
static diva_segment_alloc_access_t ifc_ref = {
|
||||
release_proc,
|
||||
segment_alloc_proc,
|
||||
segment_free_proc,
|
||||
get_segment_length_proc,
|
||||
map_address,
|
||||
umap_address,
|
||||
write_address,
|
||||
resource_removed
|
||||
};
|
||||
|
||||
#if defined(DIVA_SHARED_SEGMENT_ALLOC)
|
||||
static struct _diva_segment_alloc* shared_segment_alloc;
|
||||
static int shared_segment_alloc_count;
|
||||
#endif
|
||||
|
||||
int diva_create_segment_alloc (void* os_context, struct _diva_segment_alloc** segment_alloc)
|
||||
{
|
||||
diva_segment_alloc_t* pI = diva_os_malloc(0, sizeof(*pI));
|
||||
|
||||
#if defined(DIVA_SHARED_SEGMENT_ALLOC)
|
||||
if (shared_segment_alloc != 0) {
|
||||
shared_segment_alloc_count++;
|
||||
*segment_alloc = shared_segment_alloc;
|
||||
DBG_TRC(("shared %d segment alloc [%p]", shared_segment_alloc_count, pI))
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
pI = diva_os_malloc(0, sizeof(*pI));
|
||||
|
||||
if (pI != 0) {
|
||||
memset (pI, 0x00, sizeof(*pI));
|
||||
|
||||
pI->ifc = ifc_ref;
|
||||
|
||||
diva_q_init (&pI->free_q);
|
||||
diva_q_init (&pI->busy_q);
|
||||
|
||||
#if defined(DIVA_USERMODE) /* { */
|
||||
#if defined(LINUX) /* { */
|
||||
pI->fd = open ("/dev/DivasMAP", O_RDWR | O_NONBLOCK); /** \todo use hardware related DMA entry, needs update of XDI driver */
|
||||
pI->fd_mem = open ("/dev/mem", O_RDWR | O_NONBLOCK); /* /dev/mem is optional */
|
||||
pI->fd_xdi = open ("/dev/DivasXDI", O_RDWR | O_NONBLOCK); /* /dev/mem is optional */
|
||||
|
||||
if (pI->fd >= 0 && (pI->fd_mem >= 0 || pI->fd_xdi >= 0)) {
|
||||
*segment_alloc = pI;
|
||||
} else {
|
||||
diva_destroy_segment_alloc (&pI);
|
||||
pI = 0;
|
||||
}
|
||||
#endif /* } */
|
||||
#else /* } { */
|
||||
pI->d = (DESCRIPTOR*)os_context;
|
||||
*segment_alloc = pI;
|
||||
#endif /* } */
|
||||
}
|
||||
|
||||
if (pI != 0) {
|
||||
#if defined(DIVA_SHARED_SEGMENT_ALLOC)
|
||||
shared_segment_alloc = pI;
|
||||
shared_segment_alloc_count = 1;
|
||||
#if defined(DIVA_SHARED_SEGMENT_LOCK)
|
||||
shared_segment_alloc_count++;
|
||||
#endif
|
||||
#endif
|
||||
DBG_TRC(("created segment alloc [%p]", pI))
|
||||
}
|
||||
|
||||
return ((pI != 0) ? 0 : -1);
|
||||
}
|
||||
|
||||
int diva_destroy_segment_alloc (struct _diva_segment_alloc** segment_alloc) {
|
||||
diva_segment_alloc_t* pI = (segment_alloc != 0) ? *segment_alloc : 0;
|
||||
|
||||
#if defined(DIVA_SHARED_SEGMENT_ALLOC)
|
||||
shared_segment_alloc_count--;
|
||||
if (shared_segment_alloc_count > 0) {
|
||||
if (segment_alloc != 0)
|
||||
*segment_alloc = 0;
|
||||
DBG_TRC(("unshare %d segment alloc [%p]", shared_segment_alloc_count, segment_alloc))
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
DBG_TRC(("destroy segment alloc [%p]", segment_alloc))
|
||||
|
||||
if (pI != 0) {
|
||||
diva_entity_link_t* link;
|
||||
|
||||
shared_segment_alloc = 0;
|
||||
shared_segment_alloc_count = 0;
|
||||
|
||||
while ((link = diva_q_get_head (&pI->busy_q)) != 0) {
|
||||
diva_q_remove (&pI->busy_q, link);
|
||||
diva_q_add_tail (&pI->free_q, link);
|
||||
}
|
||||
|
||||
while ((link = diva_q_get_head (&pI->free_q)) != 0) {
|
||||
diva_map_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_map_entry_t, link);
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
munmap (pE->mem, 4*1024);
|
||||
#endif
|
||||
#else
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Req = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Rc = IDI_SYNC_REQ_PROCESS_STREAMING_MAPPING;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.request = IDI_SYNC_REQ_PROCESS_STREAMING_MAPPING_FREE_COMMAND;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo = pE->dma_lo;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_hi = pE->dma_hi;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.addr = pE->mem;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_handle = pE->entry_nr;
|
||||
pI->d->request((ENTITY*)&pI->syncReq);
|
||||
#endif
|
||||
diva_q_remove (&pI->free_q, link);
|
||||
diva_os_free (0, pE);
|
||||
}
|
||||
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
if (pI->fd >= 0)
|
||||
close (pI->fd);
|
||||
if (pI->fd_mem >= 0)
|
||||
close (pI->fd_mem);
|
||||
if (pI->fd_xdi >= 0)
|
||||
close (pI->fd_xdi);
|
||||
#endif
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
diva_os_free (0, pI);
|
||||
|
||||
*segment_alloc = 0;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void release_proc(struct _diva_segment_alloc** pI) {
|
||||
diva_destroy_segment_alloc (pI);
|
||||
}
|
||||
|
||||
void* segment_alloc_proc(struct _diva_segment_alloc* pI, dword* lo, dword* hi) {
|
||||
diva_entity_link_t* link = diva_q_get_head(&pI->free_q);
|
||||
void* addr = 0;
|
||||
|
||||
if (link != 0) {
|
||||
diva_map_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_map_entry_t, link);
|
||||
|
||||
diva_q_remove (&pI->free_q, link);
|
||||
diva_q_add_tail (&pI->busy_q, link);
|
||||
|
||||
*lo = pE->dma_lo;
|
||||
*hi = pE->dma_hi;
|
||||
|
||||
return (pE->mem);
|
||||
} else if ((link = diva_os_malloc (0, sizeof(diva_map_entry_t))) != 0) {
|
||||
diva_map_entry_t* pE = (diva_map_entry_t*)link;
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
dword data[5];
|
||||
int ret;
|
||||
|
||||
data[0] = DIVA_XDI_UM_CMD_CREATE_XDI_DESCRIPTORS;
|
||||
data[1] = 1;
|
||||
|
||||
{ int tmp = write (pI->fd, data, 2*sizeof(dword)); tmp++; }
|
||||
ret = read (pI->fd, data, sizeof(data));
|
||||
if (ret == sizeof(data) || ret == (sizeof(data)-sizeof(data[0]))) {
|
||||
if (data[0] == DIVA_XDI_UM_CMD_CREATE_XDI_DESCRIPTORS && data[1] == 1) {
|
||||
pE->dma_lo = data[3];
|
||||
pE->dma_hi = (data[2] == 8) ? data[4] : 0;
|
||||
if (map_entry(pI, pE) == 0) {
|
||||
diva_q_add_tail (&pI->busy_q, &pE->link);
|
||||
*lo = pE->dma_lo;
|
||||
*hi = pE->dma_hi;
|
||||
addr = pE->mem;
|
||||
} else {
|
||||
diva_os_free (0, pE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Req = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Rc = IDI_SYNC_REQ_PROCESS_STREAMING_MAPPING;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.request = IDI_SYNC_REQ_PROCESS_STREAMING_MAPPING_ALLOC_COMMAND;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_hi = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.addr = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_handle = -1;
|
||||
pI->d->request((ENTITY*)&pI->syncReq);
|
||||
if (pI->syncReq.diva_xdi_streaming_mapping_req.info.request == IDI_SYNC_REQ_PROCESS_STREAMING_COMMAND_OK &&
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.addr != 0) {
|
||||
pE->entry_nr = pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_handle;
|
||||
pE->dma_lo = pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo;
|
||||
pE->dma_hi = pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_hi;
|
||||
pE->mem = pI->syncReq.diva_xdi_streaming_mapping_req.info.addr;
|
||||
|
||||
*lo = pE->dma_lo;
|
||||
*hi = pE->dma_hi;
|
||||
addr = pE->mem;
|
||||
|
||||
memset (addr, 0x00, 4*1024);
|
||||
|
||||
diva_q_add_tail (&pI->busy_q, &pE->link);
|
||||
} else {
|
||||
diva_os_free (0, pE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
#if defined(DIVA_USERMODE)
|
||||
static int map_entry (struct _diva_segment_alloc* pI, diva_map_entry_t* pE) {
|
||||
void* addr;
|
||||
|
||||
if (pE->dma_hi != 0) {
|
||||
qword i = ((qword)pE->dma_lo) | (((qword)pE->dma_hi) << 32);
|
||||
#if defined(LINUX)
|
||||
addr = mmap (0, 4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, pI->fd, i);
|
||||
#endif
|
||||
} else {
|
||||
#if defined(LINUX)
|
||||
addr = mmap (0, 4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, pI->fd, pE->dma_lo);
|
||||
#endif
|
||||
}
|
||||
if (addr == 0 || addr == ((void*)-1)) {
|
||||
DBG_ERR(("failed to map %08x:%08x [%p]", pE->dma_lo, pE->dma_hi, pI))
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
pE->mem = addr;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void* map_address (struct _diva_segment_alloc* pI, dword lo, dword hi, int map_host) {
|
||||
void* ret = 0;
|
||||
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
qword addr = ((qword)lo) | (((qword)hi) << 32);
|
||||
int effective_map_fd = (map_host == 0) ? pI->fd_mem : pI->fd;
|
||||
|
||||
if (effective_map_fd >= 0) {
|
||||
ret = mmap (0, 4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, effective_map_fd, addr);
|
||||
if (ret == ((void*)-1)) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Req = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.Rc = IDI_SYNC_REQ_PROCESS_STREAMING_MAPPING;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.request = IDI_SYNC_REQ_PROCESS_STREAMING_SYSTEM_MAP_COMMAND;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_hi = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.addr = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_handle = -1;
|
||||
pI->d->request((ENTITY*)&pI->syncReq);
|
||||
if (pI->syncReq.diva_xdi_streaming_mapping_req.info.request == IDI_SYNC_REQ_PROCESS_STREAMING_COMMAND_OK) {
|
||||
byte* p = pI->syncReq.diva_xdi_streaming_mapping_req.info.addr;
|
||||
dword offset = lo - pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo;
|
||||
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.addr = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_lo = 0;
|
||||
pI->syncReq.diva_xdi_streaming_mapping_req.info.dma_hi = 0;
|
||||
|
||||
ret = p + offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void* umap_address (struct _diva_segment_alloc* ifc, dword lo, dword hi, void* local) {
|
||||
#if defined(DIVA_USERMODE)
|
||||
#if defined(LINUX)
|
||||
munmap (local, 4*1024);
|
||||
#endif
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int write_address (struct _diva_segment_alloc* pI, dword lo, dword hi, dword data) {
|
||||
diva_xdi_direct_access_cmd_t cmd;
|
||||
int ret;
|
||||
|
||||
if (unlikely(pI->fd_xdi < 0))
|
||||
return (-1);
|
||||
|
||||
|
||||
cmd.hdr.ident = DIVA_XDI_DIRECT_ACCESS_CMD_IDENT;
|
||||
cmd.hdr.cmd = DIVA_XDI_DIRECT_ACCESS_CMD_WRITE_BY_ADDRESS;
|
||||
cmd.cmd.write_by_address.address = lo;
|
||||
cmd.cmd.write_by_address.value = data;
|
||||
|
||||
ret = write (pI->fd_xdi, &cmd, sizeof(cmd.hdr)+sizeof(cmd.cmd.write_by_address)) ==
|
||||
sizeof(cmd.hdr)+sizeof(cmd.cmd.write_by_address) ? 0 : -1;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void resource_removed (struct _diva_segment_alloc* pI) {
|
||||
#if defined(DIVA_USERMODE)
|
||||
|
||||
#else
|
||||
pI->d = &diva_segment_alloc_resource_removed_descriptor;
|
||||
#endif
|
||||
}
|
||||
|
||||
void segment_free_proc(struct _diva_segment_alloc* pI, void* addr, dword lo, dword hi) {
|
||||
diva_entity_link_t* link;
|
||||
|
||||
for (link = diva_q_get_head(&pI->busy_q); link != 0; link = diva_q_get_next(link)) {
|
||||
diva_map_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_map_entry_t, link);
|
||||
|
||||
if (pE->mem == addr && pE->dma_lo == lo && pE->dma_hi == hi) {
|
||||
diva_q_remove (&pI->busy_q, link);
|
||||
diva_q_add_tail (&pI->free_q, link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_ERR(("segment not found: %p %08x:%08x [%p]", addr, lo, hi, pI))
|
||||
}
|
||||
|
||||
dword get_segment_length_proc(struct _diva_segment_alloc* pI) {
|
||||
return (4*1024);
|
||||
}
|
||||
|
||||
diva_segment_alloc_access_t* diva_get_segment_alloc_ifc (struct _diva_segment_alloc* segment_alloc) {
|
||||
return ((segment_alloc != 0) ? &segment_alloc->ifc : 0);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DIVA_SPI_DESCRIPTOR_H__
|
||||
#define __DIVA_SPI_DESCRIPTOR_H__
|
||||
|
||||
|
||||
#define MAX_SPI_DESCRIPTOR_LENGTH (4*1024)
|
||||
#define MAX_XCONN_PER_DSP_DESCRIPTORS 8
|
||||
#define SMALL_FLAT_RX_BUFFER_LENGTH 128
|
||||
|
||||
/*
|
||||
SPI descriptor is always transferred in two parts:
|
||||
byte* msg;
|
||||
|
||||
xmit(&msg[4], length-4);
|
||||
xmit(msg, 4);
|
||||
|
||||
The second transfer is used as indication about end of the
|
||||
descriptor transfer.
|
||||
*/
|
||||
|
||||
typedef struct _diva_spi_msg_hdr {
|
||||
byte length_lo; /* Total transfer length, includes the the length of the header, lo byte */
|
||||
byte length_hi; /* Total transfer length, includes the length of the header, h byte */
|
||||
byte Id; /* IDI Id. 0xff in case of the system message */
|
||||
byte Ind; /* Ind */
|
||||
} diva_spi_msg_hdr_t;
|
||||
|
||||
typedef struct _diva_spi_msg {
|
||||
diva_spi_msg_hdr_t hdr;
|
||||
byte data[MAX_SPI_DESCRIPTOR_LENGTH-sizeof(diva_spi_msg_hdr_t)];
|
||||
} diva_spi_msg_t;
|
||||
|
||||
/*
|
||||
System messages:
|
||||
if Id == 0xff then system message
|
||||
if (length_hi & 0x80) then system message is chained after the message
|
||||
|
||||
Messages:
|
||||
byte - message type
|
||||
byte - message length without this byte and the length byte
|
||||
body - sequence of bytes, depends on the type of message
|
||||
*/
|
||||
|
||||
/*
|
||||
Used for comminication with
|
||||
monitor task
|
||||
*/
|
||||
typedef struct _diva_dsp_monitor_message_hdr {
|
||||
byte length_lo; /* Total transfer length, includes the the length of the header, lo byte */
|
||||
byte length_hi; /* Total transfer length, includes the length of the header, h byte */
|
||||
byte message_lo;
|
||||
byte message_hi;
|
||||
} diva_dsp_monitor_message_hdr_t;
|
||||
|
||||
typedef struct _diva_dsp_monitor_message {
|
||||
diva_dsp_monitor_message_hdr_t hdr;
|
||||
byte data[MAX_SPI_DESCRIPTOR_LENGTH-sizeof(diva_dsp_monitor_message_hdr_t)];
|
||||
} diva_dsp_monitor_message_t;
|
||||
|
||||
/*
|
||||
Format of the request:
|
||||
length_lo
|
||||
length_hi - set to "data_length + 5"
|
||||
Id
|
||||
Req - Stored in the Ind field
|
||||
RegCh - Req Ch stored in the first byte of data field
|
||||
data - first byte of data
|
||||
*/
|
||||
|
||||
/*
|
||||
Format of the return code without extended info:
|
||||
length_lo
|
||||
length_hi - set to 6
|
||||
Id
|
||||
Rc - Stored in the Ind field
|
||||
RcCh - RcCh stored in the first byte of data field
|
||||
type - Type. Set to zero for RC, stored in the second byte of data field
|
||||
|
||||
Format of the return code with extended info:
|
||||
length_lo
|
||||
length_hi - set to 14
|
||||
Id
|
||||
Rc - Stored in the Ind field
|
||||
RcCh - RcCh stored in the first byte of data field
|
||||
type - Type. Set to zero for RC, stored in the second byte of data field
|
||||
dword - extended info type (bytes 2,3,4,5 of data field)
|
||||
dword - extended info (bytes 6,7,8,9 of data field)
|
||||
*/
|
||||
|
||||
/*
|
||||
Format of the indication:
|
||||
length_lo
|
||||
length_hi - set to "data_lengt + 6"
|
||||
Id
|
||||
Ind - Stored in the Ind field
|
||||
IndCh - IndCh stored in the first byte of data field
|
||||
type - Type. Set to one for IND, stored in the second byte of data field
|
||||
data - first byte of data, starts at third data byte
|
||||
*/
|
||||
|
||||
typedef struct _diva_xconn_msg_hdr {
|
||||
word counter;
|
||||
word length;
|
||||
} diva_xconn_msg_hdr_t;
|
||||
|
||||
typedef struct _diva_xconn_msg {
|
||||
diva_xconn_msg_hdr_t hdr;
|
||||
byte data[MAX_SPI_DESCRIPTOR_LENGTH-sizeof(diva_xconn_msg_hdr_t)];
|
||||
} diva_xconn_msg_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,338 @@
|
|||
|
||||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2010-2011
|
||||
Copyright 2000-2003 by Armin Schindler (mac@melware.de)
|
||||
Copyright 2000-2003 Cytronics & Melware (info@melware.de)
|
||||
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Dialogic range of Adapters.
|
||||
*
|
||||
Dialogic(R) File Revision : 2.1
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DIVA_XDI_UM_CFG_MESSSGE_H__
|
||||
#define __DIVA_XDI_UM_CFG_MESSAGE_H__
|
||||
|
||||
/*
|
||||
Definition of commands for user mode configuration
|
||||
utility to XDI device driver
|
||||
*/
|
||||
|
||||
/*
|
||||
XDI WRITE command
|
||||
*/
|
||||
#define DIVA_XDI_IO_CMD_WRITE_MSG 0x3701
|
||||
|
||||
/*
|
||||
XDI READ command
|
||||
*/
|
||||
#define DIVA_XDI_IO_CMD_READ_MSG 0x3702
|
||||
|
||||
|
||||
/*
|
||||
Definition of messages used to communicate between
|
||||
XDI device driver and user mode configuration utility
|
||||
*/
|
||||
|
||||
/*
|
||||
As acknowledge one DWORD - card ordinal will be read from the card
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_CARD_ORDINAL 0
|
||||
|
||||
/*
|
||||
no acknowledge will be generated, memory block will be written in the
|
||||
memory at given offset
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK 1
|
||||
|
||||
/*
|
||||
no acknowledge will be genatated, FPGA will be programmed
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_WRITE_FPGA 2
|
||||
|
||||
/*
|
||||
As acknowledge block of SDRAM will be read in the user buffer
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_READ_SDRAM 3
|
||||
|
||||
/*
|
||||
As acknowledge dword with serial number will be read in the user buffer
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_SERIAL_NR 4
|
||||
|
||||
/*
|
||||
As acknowledge struct consisting from 9 dwords with PCI info.
|
||||
dword[0...7] = 8 PCI BARS
|
||||
dword[9] = IRQ
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG 5
|
||||
|
||||
/*
|
||||
Reset of the board + activation of primary
|
||||
boot loader
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_RESET_ADAPTER 6
|
||||
|
||||
/*
|
||||
Called after code download to start adapter
|
||||
at specified address
|
||||
Start does set new set of features due to fact that we not know
|
||||
if protocol features have changed
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_START_ADAPTER 7
|
||||
|
||||
/*
|
||||
Stop adapter, called if user
|
||||
wishes to stop adapter without unload
|
||||
of the driver, to reload adapter with
|
||||
different protocol
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_STOP_ADAPTER 8
|
||||
|
||||
/*
|
||||
Get state of current adapter
|
||||
Acknowledge is one dword with following values:
|
||||
0 - adapter ready for download
|
||||
1 - adapter running
|
||||
2 - adapter dead
|
||||
3 - out of service, driver should be restarted or hardware problem
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_CARD_STATE 9
|
||||
|
||||
/*
|
||||
Reads XLOG entry from the card
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_READ_XLOG_ENTRY 10
|
||||
|
||||
/*
|
||||
Set untranslated protocol code features
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES 11
|
||||
|
||||
/*
|
||||
Start adapter test procedure
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_ADAPTER_TEST 12
|
||||
|
||||
/*
|
||||
Alloc DMA descriptor
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_ALLOC_DMA_DESCRIPTOR 14
|
||||
|
||||
|
||||
/*
|
||||
Get hardware information structure
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_HW_INFO_STRUCT 15
|
||||
|
||||
/*
|
||||
Change XDI driver protocol code version
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_SET_PROTOCOL_CODE_VERSION 17
|
||||
|
||||
/*
|
||||
Init VIDI, read VIDI info from driver
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_INIT_VIDI 18
|
||||
|
||||
/*
|
||||
Select VIDI mode
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_SET_VIDI_MODE 19
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_set_vidi_mode {
|
||||
dword vidi_mode;
|
||||
} diva_xdi_um_cfg_cmd_set_vidi_mode_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_init_vidi {
|
||||
dword req_magic_lo;
|
||||
dword req_magic_hi;
|
||||
dword ind_magic_lo;
|
||||
dword ind_magic_hi;
|
||||
|
||||
dword dma_segment_length;
|
||||
dword dma_req_buffer_length;
|
||||
dword dma_ind_buffer_length;
|
||||
dword dma_ind_remote_counter_offset;
|
||||
} diva_xdi_um_cfg_cmd_data_init_vidi_t;
|
||||
|
||||
/*
|
||||
Get clock memory info
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_GET_CLOCK_MEMORY_INFO 20
|
||||
|
||||
/*
|
||||
Read PLX register
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_READ_WRITE_PLX_REGISTER 21
|
||||
|
||||
/*
|
||||
Create DMA descriptor
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_CREATE_XDI_DESCRIPTORS 22
|
||||
|
||||
/*
|
||||
Clock interrupt
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_CLOCK_INTERRUPT_CONTROL 23
|
||||
|
||||
/*
|
||||
Clock interrupt data
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_CLOCK_INTERRUPT_DATA 24
|
||||
|
||||
/*
|
||||
BAR Access
|
||||
*/
|
||||
#define DIVA_XDI_UM_CMD_BAR_ACCESS 25
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_get_clock_memory_info {
|
||||
dword bus_addr_lo;
|
||||
dword bus_addr_hi;
|
||||
dword length;
|
||||
} diva_xdi_um_cfg_cmd_get_clock_memory_info_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_alloc_dma_descriptor {
|
||||
dword nr;
|
||||
dword low;
|
||||
dword high;
|
||||
} diva_xdi_um_cfg_cmd_data_alloc_dma_descriptor_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_adapter_test {
|
||||
dword test_command;
|
||||
} diva_xdi_um_cfg_cmd_data_adapter_test_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_set_features {
|
||||
dword features;
|
||||
} diva_xdi_um_cfg_cmd_data_set_features_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_start {
|
||||
dword offset;
|
||||
dword features;
|
||||
} diva_xdi_um_cfg_cmd_data_start_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_write_sdram {
|
||||
dword ram_number;
|
||||
dword offset;
|
||||
dword length;
|
||||
} diva_xdi_um_cfg_cmd_data_write_sdram_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_write_fpga {
|
||||
dword fpga_number;
|
||||
dword image_length;
|
||||
} diva_xdi_um_cfg_cmd_data_write_fpga_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_read_sdram {
|
||||
dword ram_number;
|
||||
dword offset;
|
||||
dword length;
|
||||
} diva_xdi_um_cfg_cmd_data_read_sdram_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_data_set_protocol_code_version {
|
||||
dword version;
|
||||
} diva_xdi_um_cfg_cmd_data_set_protocol_code_version_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_read_write_plx_register {
|
||||
byte write;
|
||||
byte offset;
|
||||
byte length;
|
||||
dword value;
|
||||
} diva_xdi_um_cfg_cmd_read_write_plx_register_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_clock_interrupt_control {
|
||||
dword command;
|
||||
} diva_xdi_um_cfg_cmd_clock_interrupt_control_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd_get_clock_interrupt_data {
|
||||
dword state;
|
||||
dword clock;
|
||||
dword errors;
|
||||
} diva_xdi_um_cfg_cmd_get_clock_interrupt_data_t;
|
||||
|
||||
#define DIVA_BAR_ACCESS_TYPE_READ 0x00
|
||||
#define DIVA_BAR_ACCESS_TYPE_WRITE 0x01
|
||||
#define DIVA_BAR_ACCESS_TYPE_SINGLE 0x02
|
||||
#define DIVA_BAR_ACCESS_TYPE_BYTE 0x04
|
||||
#define DIVA_BAR_ACCESS_TYPE_WORD 0x08
|
||||
#define DIVA_BAR_ACCESS_TYPE_DWORD 0x10
|
||||
#define DIVA_BAR_ACCESS_TYPE_WRITE_READ 0x20
|
||||
|
||||
typedef struct _diva_xdi_um_bar_access_data {
|
||||
byte bar;
|
||||
byte access_type;
|
||||
word length;
|
||||
dword offset;
|
||||
dword data;
|
||||
} diva_xdi_um_bar_access_data_t;
|
||||
|
||||
typedef union _diva_xdi_um_cfg_cmd_data {
|
||||
diva_xdi_um_cfg_cmd_data_write_sdram_t write_sdram;
|
||||
diva_xdi_um_cfg_cmd_data_write_fpga_t write_fpga;
|
||||
diva_xdi_um_cfg_cmd_data_read_sdram_t read_sdram;
|
||||
diva_xdi_um_cfg_cmd_data_start_t start;
|
||||
diva_xdi_um_cfg_cmd_data_set_features_t features;
|
||||
diva_xdi_um_cfg_cmd_data_adapter_test_t test;
|
||||
diva_xdi_um_cfg_cmd_data_alloc_dma_descriptor_t dma;
|
||||
diva_xdi_um_cfg_cmd_data_set_protocol_code_version_t protocol_code_version;
|
||||
diva_xdi_um_cfg_cmd_data_init_vidi_t vidi;
|
||||
diva_xdi_um_cfg_cmd_set_vidi_mode_t vidi_mode;
|
||||
diva_xdi_um_cfg_cmd_get_clock_memory_info_t clock_memory;
|
||||
diva_xdi_um_cfg_cmd_read_write_plx_register_t plx_register;
|
||||
diva_xdi_um_cfg_cmd_clock_interrupt_control_t clock_interrupt_control;
|
||||
diva_xdi_um_cfg_cmd_get_clock_interrupt_data_t clock_interrupt_data;
|
||||
diva_xdi_um_bar_access_data_t bar_access_data;
|
||||
} diva_xdi_um_cfg_cmd_data_t;
|
||||
|
||||
typedef struct _diva_xdi_um_cfg_cmd {
|
||||
dword adapter; /* Adapter number 1...N */
|
||||
dword command;
|
||||
diva_xdi_um_cfg_cmd_data_t command_data;
|
||||
dword data_length; /* Plain binary data will follow */
|
||||
} diva_xdi_um_cfg_cmd_t;
|
||||
|
||||
typedef struct _diva_xdi_io_cmd {
|
||||
unsigned int length;
|
||||
void * cmd;
|
||||
} diva_xdi_io_cmd;
|
||||
|
||||
/*
|
||||
* Diva direct interface access commands
|
||||
*/
|
||||
#define DIVA_XDI_DIRECT_ACCESS_CMD_IDENT 0x1234abcd
|
||||
typedef struct _diva_xdi_direct_access_cmd_hdr {
|
||||
dword ident;
|
||||
dword cmd;
|
||||
} diva_xdi_direct_access_cmd_hdr_t;
|
||||
|
||||
#define DIVA_XDI_DIRECT_ACCESS_CMD_WRITE_BY_ADDRESS 1
|
||||
typedef struct _diva_xdi_direct_access_write_by_address {
|
||||
dword address;
|
||||
dword value;
|
||||
} diva_xdi_direct_access_write_by_address_t;
|
||||
|
||||
typedef struct _diva_xdi_direct_access_cmd {
|
||||
diva_xdi_direct_access_cmd_hdr_t hdr;
|
||||
union {
|
||||
diva_xdi_direct_access_write_by_address_t write_by_address;
|
||||
} cmd;
|
||||
} diva_xdi_direct_access_cmd_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2011
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Implements interface to diva trace system
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_4
|
||||
#include <asterisk.h>
|
||||
#endif
|
||||
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/cli.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "divaverbose.h"
|
||||
|
||||
static int verbose_registered;
|
||||
AST_MUTEX_DEFINE_STATIC(dbgIfcLock);
|
||||
static volatile int divaDbgIfc = -1;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static
|
||||
#endif
|
||||
char capi_do_verbose_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " verbose\n"
|
||||
" Connect to debug driver.\n";
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
static
|
||||
#endif
|
||||
char capi_no_verbose_usage[] =
|
||||
"Usage: " CC_MESSAGE_NAME " no verbose\n"
|
||||
" Disconnect from debug driver.\n";
|
||||
|
||||
static void open_diva_mnt(void)
|
||||
{
|
||||
cc_mutex_lock(&dbgIfcLock);
|
||||
if (divaDbgIfc < 0) {
|
||||
divaDbgIfc = open("/dev/DivasDBGIFC", O_WRONLY);
|
||||
}
|
||||
cc_mutex_unlock(&dbgIfcLock);
|
||||
}
|
||||
|
||||
#if (!defined(CC_AST_HAS_VERSION_1_4) && !defined(CC_AST_HAS_VERSION_1_6) && !defined(CC_AST_HAS_VERSION_1_8))
|
||||
static void diva_verbose_write (const char *info, int opos, int replacelast, int complete)
|
||||
#else
|
||||
static void diva_verbose_write (const char *info)
|
||||
#endif
|
||||
{
|
||||
if (divaDbgIfc < 0) {
|
||||
open_diva_mnt();
|
||||
}
|
||||
if (divaDbgIfc >= 0) {
|
||||
write (divaDbgIfc, info, strlen(info));
|
||||
}
|
||||
}
|
||||
|
||||
static int diva_verbose_start(void)
|
||||
{
|
||||
if (verbose_registered == 0) {
|
||||
verbose_registered = (ast_register_verbose(diva_verbose_write) == 0);
|
||||
}
|
||||
|
||||
return ((verbose_registered != 0) ? 0 : -1);
|
||||
}
|
||||
|
||||
static int diva_verbose_stop(void)
|
||||
{
|
||||
if (verbose_registered != 0) {
|
||||
verbose_registered = !(ast_unregister_verbose(diva_verbose_write) == 0);
|
||||
}
|
||||
if ((verbose_registered == 0) && (divaDbgIfc >= 0)) {
|
||||
close(divaDbgIfc);
|
||||
divaDbgIfc = -1;
|
||||
}
|
||||
|
||||
return ((verbose_registered == 0) ? 0 : -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* enable debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
char *pbxcli_capi_do_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
int pbxcli_capi_do_verbose(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " verbose";
|
||||
e->usage = capi_do_verbose_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 2)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
ret = diva_verbose_start();
|
||||
if (ret == 0) {
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Message Verboser Enabled\n");
|
||||
} else {
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Failed to enable Message Verboser\n");
|
||||
}
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||
#else
|
||||
return ((ret == 0) ? RESULT_SUCCESS : RESULT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* disable debugging
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
char *pbxcli_capi_no_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
|
||||
#else
|
||||
int pbxcli_capi_no_verbose(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
int fd = a->fd;
|
||||
|
||||
if (cmd == CLI_INIT) {
|
||||
e->command = CC_MESSAGE_NAME " no verbose";
|
||||
e->usage = capi_no_verbose_usage;
|
||||
return NULL;
|
||||
} else if (cmd == CLI_GENERATE)
|
||||
return NULL;
|
||||
if (a->argc != e->args)
|
||||
return CLI_SHOWUSAGE;
|
||||
#else
|
||||
if (argc != 3)
|
||||
return RESULT_SHOWUSAGE;
|
||||
#endif
|
||||
|
||||
|
||||
ret = diva_verbose_stop();
|
||||
if (ret == 0) {
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Message Verboser Disabled\n");
|
||||
} else {
|
||||
ast_cli(fd, CC_MESSAGE_BIGNAME " Failed to disable Message Verboser\n");
|
||||
}
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||
#else
|
||||
return ((ret == 0) ? RESULT_SUCCESS : RESULT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void diva_verbose_load(void)
|
||||
{
|
||||
divaDbgIfc = -1;
|
||||
open_diva_mnt();
|
||||
if (divaDbgIfc >= 0) {
|
||||
diva_verbose_start();
|
||||
}
|
||||
}
|
||||
|
||||
void diva_verbose_unload(void)
|
||||
{
|
||||
if (verbose_registered != 0) {
|
||||
verbose_registered = !(ast_unregister_verbose(diva_verbose_write) == 0);
|
||||
}
|
||||
if (verbose_registered != 0)
|
||||
cc_mutex_lock(&dbgIfcLock);
|
||||
if (divaDbgIfc >= 0) {
|
||||
close(divaDbgIfc);
|
||||
divaDbgIfc = -1;
|
||||
}
|
||||
if (verbose_registered != 0)
|
||||
cc_mutex_unlock(&dbgIfcLock);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic(R), 2011
|
||||
|
||||
*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU General Public License for more details.
|
||||
*
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief Declares interface to diva trace system
|
||||
*/
|
||||
#ifndef __DIVA_VERBOSER_H__
|
||||
#define __DIVA_VERBOSER_H__
|
||||
|
||||
#ifdef DIVA_VERBOSE
|
||||
|
||||
void diva_verbose_load(void);
|
||||
void diva_verbose_unload(void);
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
char *pbxcli_capi_do_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
||||
char *pbxcli_capi_no_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
|
||||
#else
|
||||
int pbxcli_capi_do_verbose(int fd, int argc, char *argv[]);
|
||||
int pbxcli_capi_no_verbose(int fd, int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#define CC_CLI_TEXT_CAPI_DO_VERBOSE "Connect " CC_MESSAGE_BIGNAME " to debug driver"
|
||||
#define CC_CLI_TEXT_CAPI_NO_VERBOSE "Disconnect " CC_MESSAGE_BIGNAME " from debug driver"
|
||||
|
||||
|
||||
#ifndef CC_AST_HAS_VERSION_1_6
|
||||
extern char capi_do_verbose_usage[];
|
||||
extern char capi_no_verbose_usage[];
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define diva_verbose_load() do{}while(0)
|
||||
#define diva_verbose_unload() do{}while(0)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -395,7 +395,11 @@ static unsigned char *cpars[] = {
|
|||
/*39 CONNECT_ACTIVE_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3a DISCONNECT_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3b*/ 0,
|
||||
#if 0
|
||||
/*3c MANUFACTURER_IND*/ (unsigned char*)"\x03\x2b\x15\x22\x2a\x01",
|
||||
#else
|
||||
/*3c MANUFACTURER_IND dw(...)*/ (unsigned char*)"\x03\x2b\x24\x2a\x01",
|
||||
#endif
|
||||
/*3d*/ 0,
|
||||
/*3e INFO_RESP*/ (unsigned char*)"\x03\x01",
|
||||
/*3f FACILITY_RESP*/ (unsigned char*)"\x03\x20\x1f\x01",
|
||||
|
|
Loading…
Reference in New Issue