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 b25d204d2b
commit 6b88eec7bf
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)
$(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)
$(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
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

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) {
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;
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) {
cycle_foreground(tech_pvt->zchan, 0);
} 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)) {
return SWITCH_STATUS_FALSE;
goto fail;
}
wflags = ZAP_READ;
status = zap_channel_wait(tech_pvt->zchan, &wflags, chunk);
if (status == ZAP_FAIL) {
return SWITCH_STATUS_GENERR;
goto fail;
}
if (status == ZAP_TIMEOUT) {
if (timeout > 0 && !switch_test_flag(tech_pvt, TFLAG_HOLD)) {
total_to -= chunk;
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)) {
return SWITCH_STATUS_GENERR;
goto fail;
}
len = tech_pvt->read_frame.buflen;
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;
@ -509,6 +510,12 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
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)
@ -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)) {
return SWITCH_STATUS_FALSE;
goto fail;
}
len = frame->datalen;
if (zap_channel_write(tech_pvt->zchan, frame->data, frame->buflen, &len) != ZAP_SUCCESS) {
if (++tech_pvt->wr_error > 10) {
return SWITCH_STATUS_GENERR;
goto fail;
}
} else {
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;
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)
@ -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);
}
}
tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
"OpenZAP",
SPAN_CONFIG[sigmsg->channel->span_id].dialplan,
@ -875,9 +887,29 @@ static ZIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
switch_channel_t *channel = NULL;
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) {
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:
{
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_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;
short sln[512] = {0};
@ -15,6 +15,9 @@ int main(int argc, char *argv[])
exit(-1);
}
map.freqs[0] = atof("350");
map.freqs[1] = atof("440");
teletone_multi_tone_init(&mt, &map);

View File

@ -211,12 +211,12 @@
#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)) { \
int st = obj->state; \
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)); \
else zap_log(ZAP_LOG_WARNING, "VETO 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 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;
char last_error[256];
zio_event_cb_t event_callback;
void *mod_data;
uint32_t skip_read_frames;
zap_buffer_t *dtmf_buffer;
zap_buffer_t *digit_buffer;
@ -365,6 +364,7 @@ struct zap_channel {
zap_fsk_data_state_t fsk;
uint8_t fsk_buf[80];
uint32_t ring_count;
void *mod_data;
struct zap_caller_data caller_data;
struct zap_span *span;
struct zap_io_interface *zio;
@ -416,7 +416,8 @@ struct zap_span {
teletone_multi_tone_t tone_finder[ZAP_TONEMAP_INVALID+1];
zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
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_close_t close;
zio_channel_destroy_t channel_destroy;
zio_span_destroy_t span_destroy;
zio_get_alarms_t get_alarms;
zio_command_t command;
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);
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);
int zap_hash_equalkeys(void *k1, void *k2);
uint32_t zap_hash_hashfromstring(void *ky);
ZIO_CODEC_FUNCTION(zio_slin2ulaw);
ZIO_CODEC_FUNCTION(zio_ulaw2slin);
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;
typedef enum {
ZAP_CHANNEL_FEATURE_DTMF = (1 << 0),
ZAP_CHANNEL_FEATURE_CODECS = (1 << 1),
ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 2),
ZAP_CHANNEL_FEATURE_CALLERID = (1 << 3)
ZAP_CHANNEL_FEATURE_DTMF_DETECT = (1 << 0),
ZAP_CHANNEL_FEATURE_DTMF_GENERATE = (1 << 1),
ZAP_CHANNEL_FEATURE_CODECS = (1 << 2),
ZAP_CHANNEL_FEATURE_INTERVAL = (1 << 3),
ZAP_CHANNEL_FEATURE_CALLERID = (1 << 4)
} zap_channel_feature_t;
typedef enum {
@ -339,6 +340,7 @@ typedef struct zap_span zap_span_t;
#define ZIO_OPEN_ARGS (zap_channel_t *zchan)
#define ZIO_CLOSE_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_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
#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_close_t) ZIO_CLOSE_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_command_t) ZIO_COMMAND_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_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_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_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_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_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
/* 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_set_state_locked(chan, ZAP_CHANNEL_STATE_UP);
zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, "5551212");
while (chan->state == ZAP_CHANNEL_STATE_UP) {
zap_wait_flag_t flags = ZAP_READ;

View File

@ -20,8 +20,8 @@ int main(int argc, char *argv[])
teletone_generation_session_t ts;
struct ttmp tmp;
if (argc < 2) {
fprintf(stderr, "Arg Error!\n");
if (argc < 3) {
fprintf(stderr, "Arg Error! <file> <tones>\n");
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)
{
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_detected_tones(zchan);
@ -281,13 +282,14 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
case ZAP_CHANNEL_STATE_HANGUP:
{
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) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} else {
if (zap_test_flag(zchan, ZAP_CHANNEL_RINGING)) {
zap_channel_command(zchan, ZAP_COMMAND_GENERATE_RING_OFF, NULL);
}
zchan->caller_data.hangup_cause = ZAP_CAUSE_NORMAL_CLEARING;
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);
indicate = 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) {
case ZAP_CHANNEL_STATE_UP:
{
@ -399,9 +403,9 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
break;
case ZAP_CHANNEL_STATE_DOWN:
{
zap_channel_done(zchan);
sig.event_id = ZAP_SIGEVENT_STOP;
analog_data->sig_cb(&sig);
zap_channel_done(zchan);
goto done;
}
break;
@ -453,18 +457,27 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
break;
case ZAP_CHANNEL_STATE_BUSY:
{
zap_channel_done(zchan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_BUSY]);
indicate = 1;
zchan->caller_data.hangup_cause = ZAP_CAUSE_NORMAL_CIRCUIT_CONGESTION;
if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
zap_channel_done(zchan);
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;
case ZAP_CHANNEL_STATE_ATTN:
{
zap_channel_done(zchan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_ATTN]);
indicate = 1;
if (zap_test_flag(zchan, ZAP_CHANNEL_OFFHOOK) && !zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND)) {
zap_channel_done(zchan);
zap_buffer_zero(dt_buffer);
teletone_run(&ts, zchan->span->tone_map[ZAP_TONEMAP_ATTN]);
indicate = 1;
} else {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
}
}
break;
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++) {
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;
analog_data->sig_cb(&sig);
if (analog_data->sig_cb) {
analog_data->sig_cb(&sig);
}
}
}
if (zchan->detected_tones[ZAP_TONEMAP_DIAL]) {
zap_channel_command(zchan, ZAP_COMMAND_SEND_DTMF, zchan->caller_data.ani);
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) + 50;
if (zchan->detected_tones[ZAP_TONEMAP_BUSY] ||
zchan->detected_tones[ZAP_TONEMAP_FAIL1] ||
zchan->detected_tones[ZAP_TONEMAP_FAIL2] ||
zchan->detected_tones[ZAP_TONEMAP_FAIL3] ||
zchan->detected_tones[ZAP_TONEMAP_ATTN]
) {
zap_log(ZAP_LOG_ERROR, "Failure indication detected!\n");
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_BUSY);
} 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]) {
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);
@ -580,6 +610,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
}
done:
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)) {
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;
case ZAP_OOB_FLASH:

View File

@ -47,6 +47,9 @@
#ifdef ZAP_ZT_SUPPORT
#include "zap_zt.h"
#endif
#ifdef ZAP_PIKA_SUPPORT
#include "zap_pika.h"
#endif
static int time_is_init = 0;
@ -192,12 +195,12 @@ void zap_global_set_default_logger(int 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;
}
static uint32_t hashfromstring(void *ky)
uint32_t zap_hash_hashfromstring(void *ky)
{
unsigned char *str = (unsigned char *) ky;
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)
{
@ -227,7 +243,7 @@ static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
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) {
zap_clear_flag_locked(zchan, ZAP_CHANNEL_CONFIGURED);
} else {
@ -315,14 +331,13 @@ zap_status_t zap_span_close_all(void)
uint32_t i, j;
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];
for(j = 0; j < span->chan_count; j++) {
zap_channel_destroy(&span->channels[i]);
}
zap_safe_free(span->signal_data);
if (zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
for(j = 0; j < span->chan_count; j++) {
zap_channel_destroy(&span->channels[i]);
}
}
}
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");
}
}
if (!zchan->tone_session.buffer) {
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.duration = zchan->dtmf_on * (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_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:
{
/* 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_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]);
@ -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:
{
/* 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;
if (tt == ZAP_TONE_DTMF) {
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;
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;
if (tt == ZAP_TONE_DTMF) {
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:
{
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;
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;
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;
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;
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;
if (val > 10 && val < 1000) {
zchan->dtmf_on = val;
@ -1162,7 +1182,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break;
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;
if (val > 10 && val < 1000) {
zchan->dtmf_off = val;
@ -1176,7 +1196,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
break;
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 *digits = ZAP_COMMAND_OBJ_CHAR_P;
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';
zap_copy_string(str, sp, ++mlen);
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) {
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)) {
uint32_t i;
for (i = 1; i < ZAP_TONEMAP_INVALID; i++) {
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)) {
zchan->detected_tones[i] = 1;
zchan->needed_tones[i] = 0;
zchan->detected_tones[0]++;
if (++zchan->detected_tones[i]) {
zchan->needed_tones[i] = 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 {
zap_io_interface_t *wanpipe_interface;
zap_io_interface_t *zt_interface;
zap_io_interface_t *pika_interface;
} interfaces;
@ -1760,7 +1782,14 @@ static zap_status_t load_config(void)
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) {
span->type = strdup(type);
zap_log(ZAP_LOG_DEBUG, "created span %d of type %s\n", span->span_id, type);
d = 0;
} else {
@ -1886,7 +1915,7 @@ zap_status_t zap_global_init(void)
zap_isdn_init();
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;
zap_mutex_create(&globals.mutex);
@ -1914,6 +1943,19 @@ zap_status_t zap_global_init(void)
}
#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) {
zap_log(ZAP_LOG_ERROR, "Error initilizing anything.\n");
return ZAP_FAIL;
@ -1953,6 +1995,10 @@ zap_status_t zap_global_destroy(void)
if (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();
}
#endif
#ifdef ZAP_PIKA_SUPPORT
if (interfaces.pika_interface) {
pika_destroy();
}
#endif
#ifdef ZAP_WANPIPE_SUPPORT
if (interfaces.wanpipe_interface) {
wanpipe_destroy();

1012
libs/freetdm/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;
}
static ZIO_COMMAND_FUNCTION(skel_command)
{
return ZAP_FAIL;
}
static ZIO_SPAN_POLL_EVENT_FUNCTION(skel_poll_event)
{
return ZAP_FAIL;
@ -97,6 +102,11 @@ static ZIO_CHANNEL_DESTROY_FUNCTION(skel_channel_destroy)
return ZAP_FAIL;
}
static ZIO_CHANNEL_DESTROY_FUNCTION(skel_span_destroy)
{
return ZAP_FAIL;
}
static ZIO_GET_ALARMS_FUNCTION(skel_get_alarms)
{
return zap_fail;
@ -117,9 +127,11 @@ zap_status_t skel_init(zap_io_interface_t **zint)
skel_interface.wait = skel_wait;
skel_interface.read = skel_read;
skel_interface.write = skel_write;
skel_interface.command = skel_command;
skel_interface.poll_event = skel_poll_event;
skel_interface.next_event = skel_next_event;
skel_interface.channel_destroy = skel_channel_destroy;
skel_interface.span_destroy = skel_span_destroy;
skel_interface.get_alarms = skel_get_alarms;
*zint = &skel_interface;