pika-choo i choose you

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@331 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Anthony Minessale 2007-11-17 01:39:28 +00:00
parent 0230150406
commit e791b35e75
14 changed files with 1419 additions and 80 deletions

View File

@ -135,6 +135,9 @@ testtones: $(SRC)/testtones.c $(MYLIB)
detect_tones: $(SRC)/detect_tones.c $(MYLIB) detect_tones: $(SRC)/detect_tones.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/detect_tones.c -o detect_tones -lopenzap -lm $(CC) $(INCS) -L. $(SRC)/detect_tones.c -o detect_tones -lopenzap -lm
detect_dtmf: $(SRC)/detect_dtmf.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/detect_dtmf.c -o detect_dtmf -lopenzap -lm
testisdn: $(SRC)/testisdn.c $(MYLIB) testisdn: $(SRC)/testisdn.c $(MYLIB)
$(CC) $(INCS) $(ZAP_CFLAGS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread $(CC) $(INCS) $(ZAP_CFLAGS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread
@ -174,6 +177,6 @@ mod_openzap-clean:
@if [ -f mod_openzap/mod_openzap.so ] ; then cd mod_openzap && make clean ; fi @if [ -f mod_openzap/mod_openzap.so ] ; then cd mod_openzap && make clean ; fi
clean: mod_openzap-clean clean: mod_openzap-clean
rm -f $(SRC)/*.o $(SRC)/isdn/*.o $(MYLIB) *~ \#* testapp testcid testtones detect_tones priserver testisdn testanalog rm -f $(SRC)/*.o $(SRC)/isdn/*.o $(MYLIB) *~ \#* testapp testcid testtones detect_tones detect_dtmf priserver testisdn testanalog
@if [ -f $(LIBPRI)/$(LIBPRIA) ] ; then cd $(LIBPRI) && make clean ; fi @if [ -f $(LIBPRI)/$(LIBPRIA) ] ; then cd $(LIBPRI) && make clean ; fi

View File

@ -0,0 +1,33 @@
; each category is a config profile
; to apply the profile append it to a channel def in
; openzap.conf with @<profile_name>
; e.g.
; [span pika]
; name => pika
; number => pika
; fxs-channel => 1:0:1-12@default
[default]
rx-gain => 0
rx-agc-enabled => 0
rx-agc-targetPower => 0
rx-agc-minGain => 0
rx-agc-maxGain => 0
rx-agc-attackRate => 0
rx-agc-decayRate => 0
rx-agc-speechThreshold => 0
rx-vad-enabled => 0
rx-vad-activationThreshold => 0
rx-vad-activationDebounceTime => 0
rx-vad-deactivationThreshold => 0
rx-vad-deactivationDebounceTime => 0
rx-vad-preSpeechBufferSize => 0
tx-gain => 0
tx-agc-enabled => 0
tx-agc-targetPower => 0
tx-agc-minGain => 0
tx-agc-maxGain => 0
tx-agc-attackRate => 0
tx-agc-decayRate => 0
tx-agc-speechThreshold => 0

View File

@ -304,14 +304,14 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
switch (tech_pvt->zchan->type) { switch (tech_pvt->zchan->type) {
case ZAP_CHAN_TYPE_FXO: case ZAP_CHAN_TYPE_FXO:
{ {
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP); zap_set_state_locked(tech_pvt->zchan, ZAP_CHANNEL_STATE_HANGUP);
}
} }
break; break;
case ZAP_CHAN_TYPE_FXS: case ZAP_CHAN_TYPE_FXS:
{ {
if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) { if (tech_pvt->zchan->state != ZAP_CHANNEL_STATE_BUSY && tech_pvt->zchan->state != ZAP_CHANNEL_STATE_DOWN) {
if (tech_pvt->zchan->token_count) { if (tech_pvt->zchan->token_count) {
cycle_foreground(tech_pvt->zchan, 0); cycle_foreground(tech_pvt->zchan, 0);
} else { } else {
@ -466,20 +466,21 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} }
if (!switch_test_flag(tech_pvt, TFLAG_IO)) { if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
return SWITCH_STATUS_FALSE; goto fail;
} }
wflags = ZAP_READ;
status = zap_channel_wait(tech_pvt->zchan, &wflags, chunk); status = zap_channel_wait(tech_pvt->zchan, &wflags, chunk);
if (status == ZAP_FAIL) { if (status == ZAP_FAIL) {
return SWITCH_STATUS_GENERR; goto fail;
} }
if (status == ZAP_TIMEOUT) { if (status == ZAP_TIMEOUT) {
if (timeout > 0 && !switch_test_flag(tech_pvt, TFLAG_HOLD)) { if (timeout > 0 && !switch_test_flag(tech_pvt, TFLAG_HOLD)) {
total_to -= chunk; total_to -= chunk;
if (total_to <= 0) { if (total_to <= 0) {
return SWITCH_STATUS_BREAK; goto fail;
} }
} }
@ -487,12 +488,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
} }
if (!(wflags & ZAP_READ)) { if (!(wflags & ZAP_READ)) {
return SWITCH_STATUS_GENERR; goto fail;
} }
len = tech_pvt->read_frame.buflen; len = tech_pvt->read_frame.buflen;
if (zap_channel_read(tech_pvt->zchan, tech_pvt->read_frame.data, &len) != ZAP_SUCCESS) { if (zap_channel_read(tech_pvt->zchan, tech_pvt->read_frame.data, &len) != ZAP_SUCCESS) {
return SWITCH_STATUS_GENERR; goto fail;
} }
*frame = &tech_pvt->read_frame; *frame = &tech_pvt->read_frame;
@ -509,6 +510,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
fail:
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
return SWITCH_STATUS_GENERR;
} }
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id) static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
@ -530,13 +537,13 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
} }
if (!switch_test_flag(tech_pvt, TFLAG_IO)) { if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
return SWITCH_STATUS_FALSE; goto fail;
} }
len = frame->datalen; len = frame->datalen;
if (zap_channel_write(tech_pvt->zchan, frame->data, frame->buflen, &len) != ZAP_SUCCESS) { if (zap_channel_write(tech_pvt->zchan, frame->data, frame->buflen, &len) != ZAP_SUCCESS) {
if (++tech_pvt->wr_error > 10) { if (++tech_pvt->wr_error > 10) {
return SWITCH_STATUS_GENERR; goto fail;
} }
} else { } else {
tech_pvt->wr_error = 0; tech_pvt->wr_error = 0;
@ -544,6 +551,11 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
fail:
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
return SWITCH_STATUS_GENERR;
} }
static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg) static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg)
@ -833,7 +845,7 @@ zap_status_t zap_channel_from_event(zap_sigmsg_t *sigmsg, switch_core_session_t
switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->chan_number); switch_set_string(sigmsg->channel->caller_data.cid_num, sigmsg->channel->chan_number);
} }
} }
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
"OpenZAP", "OpenZAP",
SPAN_CONFIG[sigmsg->channel->span_id].dialplan, SPAN_CONFIG[sigmsg->channel->span_id].dialplan,
@ -875,9 +887,29 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
switch_channel_t *channel = NULL; switch_channel_t *channel = NULL;
zap_status_t status; zap_status_t status;
zap_log(ZAP_LOG_DEBUG, "got FXO sig [%s]\n", zap_signal_event2str(sigmsg->event_id)); zap_log(ZAP_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", sigmsg->channel->span_id, sigmsg->channel->chan_id, zap_signal_event2str(sigmsg->event_id));
switch(sigmsg->event_id) { switch(sigmsg->event_id) {
case ZAP_SIGEVENT_PROGRESS_MEDIA:
{
if ((session = zap_channel_get_session(sigmsg->channel, 0))) {
channel = switch_core_session_get_channel(session);
switch_channel_mark_pre_answered(channel);
switch_core_session_rwunlock(session);
}
}
break;
case ZAP_SIGEVENT_STOP:
{
while((session = zap_channel_get_session(sigmsg->channel, 0))) {
zap_channel_clear_token(sigmsg->channel, 0);
channel = switch_core_session_get_channel(session);
switch_channel_hangup(channel, sigmsg->channel->caller_data.hangup_cause);
switch_core_session_rwunlock(session);
}
}
break;
case ZAP_SIGEVENT_UP: case ZAP_SIGEVENT_UP:
{ {
if ((session = zap_channel_get_session(sigmsg->channel, 0))) { if ((session = zap_channel_get_session(sigmsg->channel, 0))) {

View File

@ -0,0 +1,32 @@
//#include "openzap.h"
#include "libteletone_detect.h"
int main(int argc, char *argv[])
{
int fd, b;
short sln[512] = {0};
teletone_dtmf_detect_state_t dtmf_detect = {0};
char digit_str[128] = "";
if (argc < 2) {
fprintf(stderr, "Arg Error!\n");
exit(-1);
}
teletone_dtmf_detect_init (&dtmf_detect, 8000);
if ((fd = open(argv[1], O_RDONLY)) < 0) {
fprintf(stderr, "File Error!\n", strerror(errno));
exit(-1);
}
while((b = read(fd, sln, 320)) > 0) {
teletone_dtmf_detect(&dtmf_detect, sln, b / 2);
teletone_dtmf_get(&dtmf_detect, digit_str, sizeof(digit_str));
if (*digit_str) {
printf("digit: %s\n", digit_str);
}
}
close(fd);
}

View File

@ -5,7 +5,7 @@ int main(int argc, char *argv[])
{ {
teletone_generation_session_t ts; teletone_generation_session_t ts;
teletone_multi_tone_t mt = {0}; teletone_multi_tone_t mt = {0};
teletone_tone_map_t map = {350.0, 440.0, 0.0}; teletone_tone_map_t map = {0};
int fd, b; int fd, b;
short sln[512] = {0}; short sln[512] = {0};
@ -15,6 +15,9 @@ int main(int argc, char *argv[])
exit(-1); exit(-1);
} }
map.freqs[0] = atof("350");
map.freqs[1] = atof("440");
teletone_multi_tone_init(&mt, &map); teletone_multi_tone_init(&mt, &map);

View File

@ -211,12 +211,12 @@
#define zap_set_state_locked(obj, s) if ( obj->state == s ) { \ #define zap_set_state_locked(obj, s) if ( obj->state == s ) { \
zap_log(ZAP_LOG_WARNING, "Why bother changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \ zap_log(ZAP_LOG_WARNING, "Why bother changing state on %d:%dfrom %s to %s\n", obj->span_id, obj->chan_id, zap_channel_state2str(obj->state), zap_channel_state2str(s)); \
} else if (zap_test_flag(obj, ZAP_CHANNEL_READY)) { \ } else if (zap_test_flag(obj, ZAP_CHANNEL_READY)) { \
int st = obj->state; \ int st = obj->state; \
zap_channel_set_state(obj, s); \ zap_channel_set_state(obj, s); \
if (obj->state == s) zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \ if (obj->state == s) zap_log(ZAP_LOG_DEBUG, "Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, zap_channel_state2str(st), zap_channel_state2str(s)); \
else zap_log(ZAP_LOG_WARNING, "VETO Changing state from %s to %s\n", zap_channel_state2str(st), zap_channel_state2str(s)); \ else zap_log(ZAP_LOG_WARNING, "VETO Changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, zap_channel_state2str(st), zap_channel_state2str(s)); \
} }
@ -344,7 +344,6 @@ struct zap_channel {
zap_event_t event_header; zap_event_t event_header;
char last_error[256]; char last_error[256];
zio_event_cb_t event_callback; zio_event_cb_t event_callback;
void *mod_data;
uint32_t skip_read_frames; uint32_t skip_read_frames;
zap_buffer_t *dtmf_buffer; zap_buffer_t *dtmf_buffer;
zap_buffer_t *digit_buffer; zap_buffer_t *digit_buffer;
@ -365,6 +364,7 @@ struct zap_channel {
zap_fsk_data_state_t fsk; zap_fsk_data_state_t fsk;
uint8_t fsk_buf[80]; uint8_t fsk_buf[80];
uint32_t ring_count; uint32_t ring_count;
void *mod_data;
struct zap_caller_data caller_data; struct zap_caller_data caller_data;
struct zap_span *span; struct zap_span *span;
struct zap_io_interface *zio; struct zap_io_interface *zio;
@ -416,7 +416,8 @@ struct zap_span {
teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1]; teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1];
zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN]; zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
zio_channel_outgoing_call_t outgoing_call; zio_channel_outgoing_call_t outgoing_call;
void *app_data; void *mod_data;
char *type;
}; };
@ -429,6 +430,7 @@ struct zap_io_interface {
zio_open_t open; zio_open_t open;
zio_close_t close; zio_close_t close;
zio_channel_destroy_t channel_destroy; zio_channel_destroy_t channel_destroy;
zio_span_destroy_t span_destroy;
zio_get_alarms_t get_alarms; zio_get_alarms_t get_alarms;
zio_command_t command; zio_command_t command;
zio_wait_t wait; zio_wait_t wait;
@ -505,6 +507,8 @@ void zap_global_set_default_logger(int level);
uint32_t zap_separate_string(char *buf, char delim, char **array, int arraylen); uint32_t zap_separate_string(char *buf, char delim, char **array, int arraylen);
void print_bits(uint8_t *b, int bl, char *buf, int blen, int e, uint8_t ss); void print_bits(uint8_t *b, int bl, char *buf, int blen, int e, uint8_t ss);
void print_hex_bytes(uint8_t *data, zap_size_t dlen, char *buf, zap_size_t blen); void print_hex_bytes(uint8_t *data, zap_size_t dlen, char *buf, zap_size_t blen);
int zap_hash_equalkeys(void *k1, void *k2);
uint32_t zap_hash_hashfromstring(void *ky);
ZIO_CODEC_FUNCTION(zio_slin2ulaw); ZIO_CODEC_FUNCTION(zio_slin2ulaw);
ZIO_CODEC_FUNCTION(zio_ulaw2slin); ZIO_CODEC_FUNCTION(zio_ulaw2slin);
ZIO_CODEC_FUNCTION(zio_slin2alaw); ZIO_CODEC_FUNCTION(zio_slin2alaw);

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2007, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ZAP_PIKA_H
#define ZAP_PIKA_H
#include "openzap.h"
#include "pikahmpapi.h"
/* Openzap PIKA hardware interface functions */
zap_status_t pika_init(zap_io_interface_t **zint);
zap_status_t pika_destroy(void);
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
*/

View File

@ -267,10 +267,11 @@ typedef enum {
} zap_chan_type_t; } zap_chan_type_t;
typedef enum { typedef enum {
ZAP_CHANNEL_FEATURE_DTMF = (1 << 0), ZAP_CHANNEL_FEATURE_DTMF_DETECT = (1 << 0),
ZAP_CHANNEL_FEATURE_CODECS = (1 << 1), ZAP_CHANNEL_FEATURE_DTMF_GENERATE = (1 << 1),
ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 2), ZAP_CHANNEL_FEATURE_CODECS = (1 << 2),
ZAP_CHANNEL_FEATURE_CALLERID = (1 << 3) ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 3),
ZAP_CHANNEL_FEATURE_CALLERID = (1 << 4)
} zap_channel_feature_t; } zap_channel_feature_t;
typedef enum { typedef enum {
@ -339,6 +340,7 @@ typedef struct zap_span zap_span_t;
#define ZIO_OPEN_ARGS (zap_channel_t *zchan) #define ZIO_OPEN_ARGS (zap_channel_t *zchan)
#define ZIO_CLOSE_ARGS (zap_channel_t *zchan) #define ZIO_CLOSE_ARGS (zap_channel_t *zchan)
#define ZIO_CHANNEL_DESTROY_ARGS (zap_channel_t *zchan) #define ZIO_CHANNEL_DESTROY_ARGS (zap_channel_t *zchan)
#define ZIO_SPAN_DESTROY_ARGS (zap_span_t *span)
#define ZIO_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj) #define ZIO_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj)
#define ZIO_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to) #define ZIO_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
#define ZIO_GET_ALARMS_ARGS (zap_channel_t *zchan) #define ZIO_GET_ALARMS_ARGS (zap_channel_t *zchan)
@ -356,6 +358,7 @@ typedef zap_status_t (*zio_configure_t) ZIO_CONFIGURE_ARGS ;
typedef zap_status_t (*zio_open_t) ZIO_OPEN_ARGS ; typedef zap_status_t (*zio_open_t) ZIO_OPEN_ARGS ;
typedef zap_status_t (*zio_close_t) ZIO_CLOSE_ARGS ; typedef zap_status_t (*zio_close_t) ZIO_CLOSE_ARGS ;
typedef zap_status_t (*zio_channel_destroy_t) ZIO_CHANNEL_DESTROY_ARGS ; typedef zap_status_t (*zio_channel_destroy_t) ZIO_CHANNEL_DESTROY_ARGS ;
typedef zap_status_t (*zio_span_destroy_t) ZIO_SPAN_DESTROY_ARGS ;
typedef zap_status_t (*zio_get_alarms_t) ZIO_GET_ALARMS_ARGS ; typedef zap_status_t (*zio_get_alarms_t) ZIO_GET_ALARMS_ARGS ;
typedef zap_status_t (*zio_command_t) ZIO_COMMAND_ARGS ; typedef zap_status_t (*zio_command_t) ZIO_COMMAND_ARGS ;
typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ; typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ;
@ -373,6 +376,7 @@ typedef zap_status_t (*zio_write_t) ZIO_WRITE_ARGS ;
#define ZIO_OPEN_FUNCTION(name) zap_status_t name ZIO_OPEN_ARGS #define ZIO_OPEN_FUNCTION(name) zap_status_t name ZIO_OPEN_ARGS
#define ZIO_CLOSE_FUNCTION(name) zap_status_t name ZIO_CLOSE_ARGS #define ZIO_CLOSE_FUNCTION(name) zap_status_t name ZIO_CLOSE_ARGS
#define ZIO_CHANNEL_DESTROY_FUNCTION(name) zap_status_t name ZIO_CHANNEL_DESTROY_ARGS #define ZIO_CHANNEL_DESTROY_FUNCTION(name) zap_status_t name ZIO_CHANNEL_DESTROY_ARGS
#define ZIO_SPAN_DESTROY_FUNCTION(name) zap_status_t name ZIO_SPAN_DESTROY_ARGS
#define ZIO_GET_ALARMS_FUNCTION(name) zap_status_t name ZIO_GET_ALARMS_ARGS #define ZIO_GET_ALARMS_FUNCTION(name) zap_status_t name ZIO_GET_ALARMS_ARGS
#define ZIO_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_ARGS #define ZIO_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_ARGS
#define ZIO_WAIT_FUNCTION(name) zap_status_t name ZIO_WAIT_ARGS #define ZIO_WAIT_FUNCTION(name) zap_status_t name ZIO_WAIT_ARGS
@ -410,6 +414,69 @@ typedef struct value zap_hash_val_t;
typedef struct zap_bitstream zap_bitstream_t; typedef struct zap_bitstream zap_bitstream_t;
typedef struct zap_fsk_modulator zap_fsk_modulator_t; typedef struct zap_fsk_modulator zap_fsk_modulator_t;
typedef enum {
ZAP_CAUSE_UNALLOCATED = 0,
ZAP_CAUSE_SUCCESS = 1,
ZAP_CAUSE_NO_ROUTE_TRANSIT_NET = 2,
ZAP_CAUSE_NO_ROUTE_DESTINATION = 3,
ZAP_CAUSE_CHANNEL_UNACCEPTABLE = 6,
ZAP_CAUSE_CALL_AWARDED_DELIVERED = 7,
ZAP_CAUSE_NORMAL_CLEARING = 16,
ZAP_CAUSE_USER_BUSY = 17,
ZAP_CAUSE_NO_USER_RESPONSE = 18,
ZAP_CAUSE_NO_ANSWER = 19,
ZAP_CAUSE_SUBSCRIBER_ABSENT = 20,
ZAP_CAUSE_CALL_REJECTED = 21,
ZAP_CAUSE_NUMBER_CHANGED = 22,
ZAP_CAUSE_REDIRECTION_TO_NEW_DESTINATION = 23,
ZAP_CAUSE_EXCHANGE_ROUTING_ERROR = 25,
ZAP_CAUSE_DESTINATION_OUT_OF_ORDER = 27,
ZAP_CAUSE_INVALID_NUMBER_FORMAT = 28,
ZAP_CAUSE_FACILITY_REJECTED = 29,
ZAP_CAUSE_RESPONSE_TO_STATUS_ENQUIRY = 30,
ZAP_CAUSE_NORMAL_UNSPECIFIED = 31,
ZAP_CAUSE_NORMAL_CIRCUIT_CONGESTION = 34,
ZAP_CAUSE_NETWORK_OUT_OF_ORDER = 38,
ZAP_CAUSE_NORMAL_TEMPORARY_FAILURE = 41,
ZAP_CAUSE_SWITCH_CONGESTION = 42,
ZAP_CAUSE_ACCESS_INFO_DISCARDED = 43,
ZAP_CAUSE_REQUESTED_CHAN_UNAVAIL = 44,
ZAP_CAUSE_PRE_EMPTED = 45,
ZAP_CAUSE_FACILITY_NOT_SUBSCRIBED = 50,
ZAP_CAUSE_OUTGOING_CALL_BARRED = 52,
ZAP_CAUSE_INCOMING_CALL_BARRED = 54,
ZAP_CAUSE_BEARERCAPABILITY_NOTAUTH = 57,
ZAP_CAUSE_BEARERCAPABILITY_NOTAVAIL = 58,
ZAP_CAUSE_SERVICE_UNAVAILABLE = 63,
ZAP_CAUSE_BEARERCAPABILITY_NOTIMPL = 65,
ZAP_CAUSE_CHAN_NOT_IMPLEMENTED = 66,
ZAP_CAUSE_FACILITY_NOT_IMPLEMENTED = 69,
ZAP_CAUSE_SERVICE_NOT_IMPLEMENTED = 79,
ZAP_CAUSE_INVALID_CALL_REFERENCE = 81,
ZAP_CAUSE_INCOMPATIBLE_DESTINATION = 88,
ZAP_CAUSE_INVALID_MSG_UNSPECIFIED = 95,
ZAP_CAUSE_MANDATORY_IE_MISSING = 96,
ZAP_CAUSE_MESSAGE_TYPE_NONEXIST = 97,
ZAP_CAUSE_WRONG_MESSAGE = 98,
ZAP_CAUSE_IE_NONEXIST = 99,
ZAP_CAUSE_INVALID_IE_CONTENTS = 100,
ZAP_CAUSE_WRONG_CALL_STATE = 101,
ZAP_CAUSE_RECOVERY_ON_TIMER_EXPIRE = 102,
ZAP_CAUSE_MANDATORY_IE_LENGTH_ERROR = 103,
ZAP_CAUSE_PROTOCOL_ERROR = 111,
ZAP_CAUSE_INTERWORKING = 127,
ZAP_CAUSE_ORIGINATOR_CANCEL = 487,
ZAP_CAUSE_CRASH = 500,
ZAP_CAUSE_SYSTEM_SHUTDOWN = 501,
ZAP_CAUSE_LOSE_RACE = 502,
ZAP_CAUSE_MANAGER_REQUEST = 503,
ZAP_CAUSE_BLIND_TRANSFER = 600,
ZAP_CAUSE_ATTENDED_TRANSFER = 601,
ZAP_CAUSE_ALLOTTED_TIMEOUT = 602,
ZAP_CAUSE_USER_CHALLENGE = 603,
ZAP_CAUSE_MEDIA_TIMEOUT = 604
} zap_call_cause_t;
#endif #endif
/* For Emacs: /* For Emacs:

View File

@ -14,7 +14,8 @@ static void *test_call(zap_thread_t *me, void *obj)
zap_log(ZAP_LOG_DEBUG, "answer call and start echo test\n"); zap_log(ZAP_LOG_DEBUG, "answer call and start echo test\n");
zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP); zap_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, "5551212");
while (chan->state == ZAP_CHANNEL_STATE_UP) { while (chan->state == ZAP_CHANNEL_STATE_UP) {
zap_wait_flag_t flags = ZAP_READ; zap_wait_flag_t flags = ZAP_READ;

View File

@ -20,8 +20,8 @@ int main(int argc, char *argv[])
teletone_generation_session_t ts; teletone_generation_session_t ts;
struct ttmp tmp; struct ttmp tmp;
if (argc < 2) { if (argc < 3) {
fprintf(stderr, "Arg Error!\n"); fprintf(stderr, "Arg Error! <file> <tones>\n");
exit(-1); exit(-1);
} }

View File

@ -44,7 +44,8 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj);
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call) static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxo_outgoing_call)
{ {
if (!zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) { if (!zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_INTHREAD)) {
//zap_channel_command(zchan, ZAP_COMMAND_TRACE_INPUT, "/tmp/inbound.ul"); zap_channel_command(zchan, ZAP_COMMAND_TRACE_INPUT, "/tmp/inbound.ul");
zap_channel_command(zchan, ZAP_COMMAND_TRACE_OUTPUT, "/tmp/outbound.ul");
zap_channel_clear_needed_tones(zchan); zap_channel_clear_needed_tones(zchan);
zap_channel_clear_detected_tones(zchan); zap_channel_clear_detected_tones(zchan);
@ -281,13 +282,14 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
case ZAP_CHANNEL_STATE_HANGUP: case ZAP_CHANNEL_STATE_HANGUP:
{ {
if (state_counter > 500) { if (state_counter > 500) {
if (zap_test_flag(zchan, ZAP_CHANNEL_RINGING)) {
zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
}
if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && zchan->last_state >= ZAP_CHANNEL_STATE_IDLE) { if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && zchan->last_state >= ZAP_CHANNEL_STATE_IDLE) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} else { } else {
if (zap_test_flag(zchan, ZAP_CHANNEL_RINGING)) { zchan->caller_data.hangup_cause = ZAP_CAUSE_NORMAL_CLEARING;
zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
}
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
} }
} }
@ -346,7 +348,9 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
zap_clear_flag_locked(zchan->span, ZAP_SPAN_STATE_CHANGE); zap_clear_flag_locked(zchan->span, ZAP_SPAN_STATE_CHANGE);
indicate = 0; indicate = 0;
state_counter = 0; state_counter = 0;
zap_log(ZAP_LOG_DEBUG, "Executing state handler for %s\n", zap_channel_state2str(zchan->state)); zap_log(ZAP_LOG_DEBUG, "Executing state handler on %d:%d for %s\n",
zchan->span_id, zchan->chan_id,
zap_channel_state2str(zchan->state));
switch(zchan->state) { switch(zchan->state) {
case ZAP_CHANNEL_STATE_UP: case ZAP_CHANNEL_STATE_UP:
{ {
@ -399,9 +403,9 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
break; break;
case ZAP_CHANNEL_STATE_DOWN: case ZAP_CHANNEL_STATE_DOWN:
{ {
zap_channel_done(zchan);
sig.event_id = ZAP_SIGEVENT_STOP; sig.event_id = ZAP_SIGEVENT_STOP;
analog_data->sig_cb(&sig); analog_data->sig_cb(&sig);
zap_channel_done(zchan);
goto done; goto done;
} }
break; break;
@ -453,18 +457,27 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
break; break;
case ZAP_CHANNEL_STATE_BUSY: case ZAP_CHANNEL_STATE_BUSY:
{ {
zap_channel_done(zchan); zchan->caller_data.hangup_cause = ZAP_CAUSE_NORMAL_CIRCUIT_CONGESTION;
zap_buffer_zero(dt_buffer); if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_BUSY]); zap_channel_done(zchan);
indicate = 1; zap_buffer_zero(dt_buffer);
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_BUSY]);
indicate = 1;
} else {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
}
} }
break; break;
case ZAP_CHANNEL_STATE_ATTN: case ZAP_CHANNEL_STATE_ATTN:
{ {
zap_channel_done(zchan); if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
zap_buffer_zero(dt_buffer); zap_channel_done(zchan);
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_ATTN]); zap_buffer_zero(dt_buffer);
indicate = 1; teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_ATTN]);
indicate = 1;
} else {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
}
} }
break; break;
default: default:
@ -514,25 +527,42 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
for (i = 1; i < ZAP_TONEMAP_INVALID; i++) { for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
if (zchan->detected_tones[i]) { if (zchan->detected_tones[i]) {
zap_log(ZAP_LOG_DEBUG, "Detected tone %s\n", zap_tonemap2str(zchan->detected_tones[i])); zap_log(ZAP_LOG_DEBUG, "Detected tone %s on %d:%d\n", zap_tonemap2str(i), zchan->span_id, zchan->chan_id);
sig.raw_data = &i; sig.raw_data = &i;
analog_data->sig_cb(&sig); if (analog_data->sig_cb) {
analog_data->sig_cb(&sig);
}
} }
} }
if (zchan->detected_tones[ZAP_TONEMAP_DIAL]) { if (zchan->detected_tones[ZAP_TONEMAP_BUSY] ||
zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani); zchan->detected_tones[ZAP_TONEMAP_FAIL1] ||
state_counter = 0; zchan->detected_tones[ZAP_TONEMAP_FAIL2] ||
zchan->needed_tones[ZAP_TONEMAP_RING] = 1; zchan->detected_tones[ZAP_TONEMAP_FAIL3] ||
zchan->needed_tones[ZAP_TONEMAP_BUSY] = 1; zchan->detected_tones[ZAP_TONEMAP_ATTN]
zchan->needed_tones[ZAP_TONEMAP_FAIL1] = 1; ) {
zchan->needed_tones[ZAP_TONEMAP_FAIL2] = 1; zap_log(ZAP_LOG_ERROR, "Failure indication detected!\n");
zchan->needed_tones[ZAP_TONEMAP_FAIL3] = 1; zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
dial_timeout = (zchan->dtmf_on + zchan->dtmf_off) * strlen(zchan->caller_data.ani) + 50; } else if (zchan->detected_tones[ZAP_TONEMAP_DIAL]) {
if (zap_strlen_zero(zchan->caller_data.ani)) {
zap_log(ZAP_LOG_ERROR, "No Digits to send!\n");
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} else {
if (zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Send Digits Failed [%s]\n", zchan->last_error);
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} else {
state_counter = 0;
zchan->needed_tones[ZAP_TONEMAP_RING] = 1;
zchan->needed_tones[ZAP_TONEMAP_BUSY] = 1;
zchan->needed_tones[ZAP_TONEMAP_FAIL1] = 1;
zchan->needed_tones[ZAP_TONEMAP_FAIL2] = 1;
zchan->needed_tones[ZAP_TONEMAP_FAIL3] = 1;
dial_timeout = ((zchan->dtmf_on + zchan->dtmf_off) * strlen(zchan->caller_data.ani)) + 3000;
}
}
} else if (zchan->detected_tones[ZAP_TONEMAP_RING]) { } else if (zchan->detected_tones[ZAP_TONEMAP_RING]) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_UP); zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_UP);
} else if (zchan->detected_tones[ZAP_TONEMAP_BUSY]) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} }
zap_channel_clear_detected_tones(zchan); zap_channel_clear_detected_tones(zchan);
@ -580,6 +610,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
} }
done: done:
zap_channel_done(zchan); zap_channel_done(zchan);
@ -647,7 +678,10 @@ static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *even
if (zap_test_flag(event->channel, ZAP_CHANNEL_RINGING)) { if (zap_test_flag(event->channel, ZAP_CHANNEL_RINGING)) {
zap_channel_command(event->channel, ZAP_COMMAND_GENERATE_RING_OFF, NULL); zap_channel_command(event->channel, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
} }
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN);
if (event->channel->state != ZAP_CHANNEL_STATE_DOWN) {
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_DOWN);
}
} }
break; break;
case ZAP_OOB_FLASH: case ZAP_OOB_FLASH:

View File

@ -47,6 +47,9 @@
#ifdef ZAP_ZT_SUPPORT #ifdef ZAP_ZT_SUPPORT
#include "zap_zt.h" #include "zap_zt.h"
#endif #endif
#ifdef ZAP_PIKA_SUPPORT
#include "zap_pika.h"
#endif
static int time_is_init = 0; static int time_is_init = 0;
@ -192,12 +195,12 @@ void zap_global_set_default_logger(int level)
zap_log_level = level; zap_log_level = level;
} }
static int equalkeys(void *k1, void *k2) int zap_hash_equalkeys(void *k1, void *k2)
{ {
return strcmp((char *) k1, (char *) k2) ? 0 : 1; return strcmp((char *) k1, (char *) k2) ? 0 : 1;
} }
static uint32_t hashfromstring(void *ky) uint32_t zap_hash_hashfromstring(void *ky)
{ {
unsigned char *str = (unsigned char *) ky; unsigned char *str = (unsigned char *) ky;
uint32_t hash = 0; uint32_t hash = 0;
@ -211,6 +214,19 @@ static uint32_t hashfromstring(void *ky)
} }
static zap_status_t zap_span_destroy(zap_span_t *span)
{
zap_status_t status = ZAP_FAIL;
if (zap_test_flag(span, ZAP_SPAN_CONFIGURED) && span->zio && span->zio->span_destroy) {
zap_log(ZAP_LOG_INFO, "Destroying span %u type (%s)\n", span->span_id, span->type);
status = span->zio->span_destroy(span);
zap_safe_free(span->type);
}
return status;
}
static zap_status_t zap_channel_destroy(zap_channel_t *zchan) static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
{ {
@ -227,7 +243,7 @@ static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
if (zchan->span->zio->channel_destroy) { if (zchan->span->zio->channel_destroy) {
zap_log(ZAP_LOG_INFO, "Closing channel %u:%u fd:%d\n", zchan->span_id, zchan->chan_id, zchan->sockfd); zap_log(ZAP_LOG_INFO, "Closing channel %s:%u:%u fd:%d\n", zchan->span->type, zchan->span_id, zchan->chan_id, zchan->sockfd);
if (zchan->span->zio->channel_destroy(zchan) == ZAP_SUCCESS) { if (zchan->span->zio->channel_destroy(zchan) == ZAP_SUCCESS) {
zap_clear_flag_locked(zchan, ZAP_CHANNEL_CONFIGURED); zap_clear_flag_locked(zchan, ZAP_CHANNEL_CONFIGURED);
} else { } else {
@ -315,14 +331,13 @@ zap_status_t zap_span_close_all(void)
uint32_t i, j; uint32_t i, j;
zap_mutex_lock(globals.mutex); zap_mutex_lock(globals.mutex);
for(i = 0; i < globals.span_index; i++) { for(i = 1; i <= globals.span_index; i++) {
span = &globals.spans[i]; span = &globals.spans[i];
if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
for(j = 0; j < span->chan_count; j++) { for(j = 0; j < span->chan_count; j++) {
zap_channel_destroy(&span->channels[i]); zap_channel_destroy(&span->channels[i]);
} }
}
zap_safe_free(span->signal_data);
} }
zap_mutex_unlock(globals.mutex); zap_mutex_unlock(globals.mutex);
@ -938,6 +953,7 @@ static zap_status_t zchan_activate_dtmf_buffer(zap_channel_t *zchan)
zap_log(ZAP_LOG_DEBUG, "Created DTMF Buffer!\n"); zap_log(ZAP_LOG_DEBUG, "Created DTMF Buffer!\n");
} }
} }
if (!zchan->tone_session.buffer) { if (!zchan->tone_session.buffer) {
memset(&zchan->tone_session, 0, sizeof(zchan->tone_session)); memset(&zchan->tone_session, 0, sizeof(zchan->tone_session));
@ -947,6 +963,8 @@ static zap_status_t zchan_activate_dtmf_buffer(zap_channel_t *zchan)
zchan->tone_session.rate = zchan->rate; zchan->tone_session.rate = zchan->rate;
zchan->tone_session.duration = zchan->dtmf_on * (zchan->tone_session.rate / 1000); zchan->tone_session.duration = zchan->dtmf_on * (zchan->tone_session.rate / 1000);
zchan->tone_session.wait = zchan->dtmf_off * (zchan->tone_session.rate / 1000); zchan->tone_session.wait = zchan->dtmf_off * (zchan->tone_session.rate / 1000);
zchan->tone_session.volume = -7;
/* /*
zchan->tone_session.debug = 1; zchan->tone_session.debug = 1;
zchan->tone_session.debug_stream = stdout; zchan->tone_session.debug_stream = stdout;
@ -1083,6 +1101,8 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
case ZAP_COMMAND_ENABLE_PROGRESS_DETECT: case ZAP_COMMAND_ENABLE_PROGRESS_DETECT:
{ {
/* if they don't have thier own, use ours */ /* if they don't have thier own, use ours */
zap_channel_clear_detected_tones(zchan);
zap_channel_clear_needed_tones(zchan);
teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_DIAL], &zchan->span->tone_detect_map[ZAP_TONEMAP_DIAL]); teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_DIAL], &zchan->span->tone_detect_map[ZAP_TONEMAP_DIAL]);
teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_RING], &zchan->span->tone_detect_map[ZAP_TONEMAP_RING]); teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_RING], &zchan->span->tone_detect_map[ZAP_TONEMAP_RING]);
teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_BUSY], &zchan->span->tone_detect_map[ZAP_TONEMAP_BUSY]); teletone_multi_tone_init(&zchan->span->tone_finder[ZAP_TONEMAP_BUSY], &zchan->span->tone_detect_map[ZAP_TONEMAP_BUSY]);
@ -1101,7 +1121,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
case ZAP_COMMAND_ENABLE_DTMF_DETECT: case ZAP_COMMAND_ENABLE_DTMF_DETECT:
{ {
/* if they don't have thier own, use ours */ /* if they don't have thier own, use ours */
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT; zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
if (tt == ZAP_TONE_DTMF) { if (tt == ZAP_TONE_DTMF) {
teletone_dtmf_detect_init (&zchan->dtmf_detect, zchan->rate); teletone_dtmf_detect_init (&zchan->dtmf_detect, zchan->rate);
@ -1117,7 +1137,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break; break;
case ZAP_COMMAND_DISABLE_DTMF_DETECT: case ZAP_COMMAND_DISABLE_DTMF_DETECT:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT; zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
if (tt == ZAP_TONE_DTMF) { if (tt == ZAP_TONE_DTMF) {
teletone_dtmf_detect_init (&zchan->dtmf_detect, zchan->rate); teletone_dtmf_detect_init (&zchan->dtmf_detect, zchan->rate);
@ -1132,7 +1152,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
} }
case ZAP_COMMAND_GET_DTMF_ON_PERIOD: case ZAP_COMMAND_GET_DTMF_ON_PERIOD:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
ZAP_COMMAND_OBJ_INT = zchan->dtmf_on; ZAP_COMMAND_OBJ_INT = zchan->dtmf_on;
GOTO_STATUS(done, ZAP_SUCCESS); GOTO_STATUS(done, ZAP_SUCCESS);
} }
@ -1140,7 +1160,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break; break;
case ZAP_COMMAND_GET_DTMF_OFF_PERIOD: case ZAP_COMMAND_GET_DTMF_OFF_PERIOD:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
ZAP_COMMAND_OBJ_INT = zchan->dtmf_on; ZAP_COMMAND_OBJ_INT = zchan->dtmf_on;
GOTO_STATUS(done, ZAP_SUCCESS); GOTO_STATUS(done, ZAP_SUCCESS);
} }
@ -1148,7 +1168,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break; break;
case ZAP_COMMAND_SET_DTMF_ON_PERIOD: case ZAP_COMMAND_SET_DTMF_ON_PERIOD:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
int val = ZAP_COMMAND_OBJ_INT; int val = ZAP_COMMAND_OBJ_INT;
if (val > 10 && val < 1000) { if (val > 10 && val < 1000) {
zchan->dtmf_on = val; zchan->dtmf_on = val;
@ -1162,7 +1182,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break; break;
case ZAP_COMMAND_SET_DTMF_OFF_PERIOD: case ZAP_COMMAND_SET_DTMF_OFF_PERIOD:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
int val = ZAP_COMMAND_OBJ_INT; int val = ZAP_COMMAND_OBJ_INT;
if (val > 10 && val < 1000) { if (val > 10 && val < 1000) {
zchan->dtmf_off = val; zchan->dtmf_off = val;
@ -1176,7 +1196,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break; break;
case ZAP_COMMAND_SEND_DTMF: case ZAP_COMMAND_SEND_DTMF:
{ {
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) { if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_GENERATE)) {
char *cur; char *cur;
char *digits = ZAP_COMMAND_OBJ_CHAR_P; char *digits = ZAP_COMMAND_OBJ_CHAR_P;
int x = 0; int x = 0;
@ -1523,7 +1543,7 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data
*(str+mlen) = '\0'; *(str+mlen) = '\0';
zap_copy_string(str, sp, ++mlen); zap_copy_string(str, sp, ++mlen);
zap_clean_string(str); zap_clean_string(str);
zap_log(ZAP_LOG_ERROR, "FSK: TYPE %s LEN %d VAL [%s]\n", zap_mdmf_type2str(type), mlen-1, str); zap_log(ZAP_LOG_DEBUG, "FSK: TYPE %s LEN %d VAL [%s]\n", zap_mdmf_type2str(type), mlen-1, str);
switch(type) { switch(type) {
case MDMF_DDN: case MDMF_DDN:
@ -1570,13 +1590,14 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data
if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) { if (zap_test_flag(zchan, ZAP_CHANNEL_PROGRESS_DETECT)) {
uint32_t i; uint32_t i;
for (i = 1; i < ZAP_TONEMAP_INVALID; i++) { for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
if (zchan->span->tone_finder[i].tone_count) { if (zchan->span->tone_finder[i].tone_count) {
if (zchan->needed_tones[i] && teletone_multi_tone_detect(&zchan->span->tone_finder[i], sln, (int)slen)) { if (zchan->needed_tones[i] && teletone_multi_tone_detect(&zchan->span->tone_finder[i], sln, (int)slen)) {
zchan->detected_tones[i] = 1; if (++zchan->detected_tones[i]) {
zchan->needed_tones[i] = 0; zchan->needed_tones[i] = 0;
zchan->detected_tones[0]++; zchan->detected_tones[0]++;
}
} }
} }
} }
@ -1713,6 +1734,7 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t data
static struct { static struct {
zap_io_interface_t *wanpipe_interface; zap_io_interface_t *wanpipe_interface;
zap_io_interface_t *zt_interface; zap_io_interface_t *zt_interface;
zap_io_interface_t *pika_interface;
} interfaces; } interfaces;
@ -1760,7 +1782,14 @@ static zap_status_t load_config(void)
continue; continue;
} }
if (!zio->configure_span) {
zap_log(ZAP_LOG_CRIT, "failure creating span, no configure_span method for '%s'\n", type);
span = NULL;
continue;
}
if (zap_span_create(zio, &span) == ZAP_SUCCESS) { if (zap_span_create(zio, &span) == ZAP_SUCCESS) {
span->type = strdup(type);
zap_log(ZAP_LOG_DEBUG, "created span %d of type %s\n", span->span_id, type); zap_log(ZAP_LOG_DEBUG, "created span %d of type %s\n", span->span_id, type);
d = 0; d = 0;
} else { } else {
@ -1886,7 +1915,7 @@ zap_status_t zap_global_init(void)
zap_isdn_init(); zap_isdn_init();
memset(&interfaces, 0, sizeof(interfaces)); memset(&interfaces, 0, sizeof(interfaces));
globals.interface_hash = create_hashtable(16, hashfromstring, equalkeys); globals.interface_hash = create_hashtable(16, zap_hash_hashfromstring, zap_hash_equalkeys);
modcount = 0; modcount = 0;
zap_mutex_create(&globals.mutex); zap_mutex_create(&globals.mutex);
@ -1914,6 +1943,19 @@ zap_status_t zap_global_init(void)
} }
#endif #endif
#ifdef ZAP_PIKA_SUPPORT
if (pika_init(&interfaces.pika_interface) == ZAP_SUCCESS) {
zap_mutex_lock(globals.mutex);
hashtable_insert(globals.interface_hash, (void *)interfaces.pika_interface->name, interfaces.pika_interface);
process_module_config(interfaces.pika_interface);
zap_mutex_unlock(globals.mutex);
modcount++;
} else {
zap_log(ZAP_LOG_ERROR, "Error initilizing pika.\n");
}
#endif
if (!modcount) { if (!modcount) {
zap_log(ZAP_LOG_ERROR, "Error initilizing anything.\n"); zap_log(ZAP_LOG_ERROR, "Error initilizing anything.\n");
return ZAP_FAIL; return ZAP_FAIL;
@ -1953,6 +1995,10 @@ zap_status_t zap_global_destroy(void)
if (cur_span->mutex) { if (cur_span->mutex) {
zap_mutex_destroy(&cur_span->mutex); zap_mutex_destroy(&cur_span->mutex);
} }
zap_safe_free(cur_span->signal_data);
zap_span_destroy(cur_span);
} }
} }
@ -1962,6 +2008,13 @@ zap_status_t zap_global_destroy(void)
zt_destroy(); zt_destroy();
} }
#endif #endif
#ifdef ZAP_PIKA_SUPPORT
if (interfaces.pika_interface) {
pika_destroy();
}
#endif
#ifdef ZAP_WANPIPE_SUPPORT #ifdef ZAP_WANPIPE_SUPPORT
if (interfaces.wanpipe_interface) { if (interfaces.wanpipe_interface) {
wanpipe_destroy(); wanpipe_destroy();

1012
libs/openzap/src/zap_pika.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -82,6 +82,11 @@ static ZIO_WRITE_FUNCTION(skel_write)
return ZAP_FAIL; return ZAP_FAIL;
} }
static ZIO_COMMAND_FUNCTION(skel_command)
{
return ZAP_FAIL;
}
static ZIO_SPAN_POLL_EVENT_FUNCTION(skel_poll_event) static ZIO_SPAN_POLL_EVENT_FUNCTION(skel_poll_event)
{ {
return ZAP_FAIL; return ZAP_FAIL;
@ -97,6 +102,11 @@ static ZIO_CHANNEL_DESTROY_FUNCTION(skel_channel_destroy)
return ZAP_FAIL; return ZAP_FAIL;
} }
static ZIO_CHANNEL_DESTROY_FUNCTION(skel_span_destroy)
{
return ZAP_FAIL;
}
static ZIO_GET_ALARMS_FUNCTION(skel_get_alarms) static ZIO_GET_ALARMS_FUNCTION(skel_get_alarms)
{ {
return zap_fail; return zap_fail;
@ -117,9 +127,11 @@ zap_status_t skel_init(zap_io_interface_t **zint)
skel_interface.wait = skel_wait; skel_interface.wait = skel_wait;
skel_interface.read = skel_read; skel_interface.read = skel_read;
skel_interface.write = skel_write; skel_interface.write = skel_write;
skel_interface.command = skel_command;
skel_interface.poll_event = skel_poll_event; skel_interface.poll_event = skel_poll_event;
skel_interface.next_event = skel_next_event; skel_interface.next_event = skel_next_event;
skel_interface.channel_destroy = skel_channel_destroy; skel_interface.channel_destroy = skel_channel_destroy;
skel_interface.span_destroy = skel_span_destroy;
skel_interface.get_alarms = skel_get_alarms; skel_interface.get_alarms = skel_get_alarms;
*zint = &skel_interface; *zint = &skel_interface;