X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=chan_lcr.c;h=52c2a3121a13762fb30ee200ff7d2463258e5bed;hp=cb6b0565f1b08c4d22ba45775c381a426cdc636e;hb=b1ab2b9ac1cfc15d2a8f5850145dd69043cc3ef7;hpb=e89c3604055d0a62a2d9c603d8bd2b30c89d71ac diff --git a/chan_lcr.c b/chan_lcr.c index cb6b056..52c2a31 100644 --- a/chan_lcr.c +++ b/chan_lcr.c @@ -295,6 +295,7 @@ struct chan_call *alloc_call(void) free_call(*callp); return(NULL); } + fcntl((*callp)->pipe[0], F_SETFL, O_NONBLOCK); CDEBUG(*callp, NULL, "Call instance allocated.\n"); return(*callp); } @@ -456,12 +457,12 @@ void apply_opt(struct chan_call *call, char *data) break; case 't': if (opt[1] != '\0') { - CERROR(call, call->ast, "Option 't' (transparent) expects no parameter.\n", opt); + CERROR(call, call->ast, "Option 't' (no_dsp) expects no parameter.\n", opt); break; } - CDEBUG(call, call->ast, "Option 't' (transparent).\n"); - if (!call->transparent) { - call->transparent = 1; + CDEBUG(call, call->ast, "Option 't' (no dsp).\n"); + if (!call->nodsp) { + call->nodsp = 1; newmode = 1; } break; @@ -476,7 +477,7 @@ void apply_opt(struct chan_call *call, char *data) bchannel_pipeline(call->bchannel, call->pipeline); break; case 'r': - if (opt[1] == '\0') { + if (opt[1] != '\0') { CERROR(call, call->ast, "Option 'r' (re-buffer 160 bytes) expects no parameter.\n", opt); break; } @@ -523,7 +524,7 @@ todo /* re-open, if bchannel is created */ if (call->bchannel && call->bchannel->b_sock > -1) { bchannel_destroy(call->bchannel); - if (bchannel_create(call->bchannel, ((call->transparent)?1:0) + ((call->hdlc)?2:0))) + if (bchannel_create(call->bchannel, ((call->nodsp)?1:0) + ((call->hdlc)?2:0))) bchannel_activate(call->bchannel, 1); } } @@ -591,11 +592,12 @@ static void send_setup_to_lcr(struct chan_call *call) newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN; } newparam.setup.capainfo.bearer_capa = ast->transfercapability; + newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT; if (call->hdlc) - newparam.setup.capainfo.bearer_mode = INFO_BMODE_PACKET; + newparam.setup.capainfo.source_mode = B_MODE_HDLC; else { + newparam.setup.capainfo.source_mode = B_MODE_TRANSPARENT; newparam.setup.capainfo.bearer_info1 = (options.law=='a')?3:2; - newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT; } newparam.setup.capainfo.hlc = INFO_HLC_NONE; newparam.setup.capainfo.exthlc = INFO_HLC_NONE; @@ -745,10 +747,10 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c } call->pbx_started = 1; // if (call->state == CHAN_LCR_STATE_IN_DIALING) -// ast_setstate(ast, AST_STATE_DIALING); + ast_setstate(ast, AST_STATE_RINGING); // else -// ast_setstate(ast, AST_STATE_OFFHOOK); - return; +// ast_setstate(ast, AST_STATE_RINGING); +// return; } /* @@ -817,9 +819,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet } ast->transfercapability = param->setup.capainfo.bearer_capa; /* enable hdlc if transcap is data */ - if (ast->transfercapability == INFO_BC_DATAUNRESTRICTED - || ast->transfercapability == INFO_BC_DATARESTRICTED - || ast->transfercapability == INFO_BC_VIDEO) + if (param->setup.capainfo.source_mode == B_MODE_HDLC) call->hdlc = 1; strncpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international), sizeof(call->oad)-1); @@ -1142,7 +1142,7 @@ int receive_message(int message_type, unsigned int ref, union parameter *param) bchannel_join(bchannel, call->bridge_id); } /* create only, if call exists, othewhise it bchannel is freed below... */ - if (bchannel_create(bchannel, ((call->transparent)?1:0) + ((call->hdlc)?2:0))) + if (bchannel_create(bchannel, ((call->nodsp)?1:0) + ((call->hdlc)?2:0))) bchannel_activate(bchannel, 1); } /* acknowledge */ @@ -1428,7 +1428,6 @@ int handle_socket(void) int open_socket(void) { int ret; - char *socket_name = SOCKET_NAME; int conn; struct sockaddr_un sock_address; unsigned int on = 1; @@ -1444,7 +1443,7 @@ int open_socket(void) /* set socket address and name */ memset(&sock_address, 0, sizeof(sock_address)); sock_address.sun_family = PF_UNIX; - strcpy(sock_address.sun_path, socket_name); + sprintf(sock_address.sun_path, SOCKET_NAME, options.lock); /* connect socket */ if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0) @@ -1900,7 +1899,7 @@ static int lcr_hangup(struct ast_channel *ast) if (ast->hangupcause > 0) send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL); else - send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL); + send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL); /* remove call */ free_call(call); if (!pthread_equal(tid, chan_tid)) @@ -1951,8 +1950,7 @@ static int lcr_write(struct ast_channel *ast, struct ast_frame *f) static struct ast_frame *lcr_read(struct ast_channel *ast) { struct chan_call *call; - int i, len; - unsigned char *p; + int len; ast_mutex_lock(&chan_lock); call = ast->tech_pvt; @@ -1961,24 +1959,23 @@ static struct ast_frame *lcr_read(struct ast_channel *ast) return NULL; } if (call->pipe[0] > -1) { - if (call->rebuffer) { + if (call->rebuffer && !call->hdlc) { len = read(call->pipe[0], call->read_buff, 160); } else { len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff)); } + if (len < 0 && errno == EAGAIN) { + ast_mutex_unlock(&chan_lock); + return &ast_null_frame; + } if (len <= 0) { close(call->pipe[0]); call->pipe[0] = -1; + ast_mutex_unlock(&chan_lock); return NULL; } } - p = call->read_buff; - for (i = 0; i < len; i++) { - *p = flip_bits[*p]; - p++; - } - call->read_fr.frametype = AST_FRAME_VOICE; call->read_fr.subclass = ast->nativeformats; call->read_fr.datalen = len; @@ -2098,21 +2095,25 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz /* * fixup asterisk */ -static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *newast) +static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *ast) { struct chan_call *call; + if (!ast) { + return -1; + } + ast_mutex_lock(&chan_lock); - call = oldast->tech_pvt; + call = ast->tech_pvt; if (!call) { - CERROR(NULL, oldast, "Received fixup from Asterisk, but no call instance exists.\n"); + CERROR(NULL, ast, "Received fixup from Asterisk, but no call instance exists.\n"); ast_mutex_unlock(&chan_lock); return -1; } - CDEBUG(call, oldast, "Received fixup from Asterisk.\n"); - call->ast = newast; - ast_mutex_lock(&chan_lock); + CDEBUG(call, ast, "Received fixup from Asterisk.\n"); + call->ast = ast; + ast_mutex_unlock(&chan_lock); return 0; } @@ -2162,23 +2163,35 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, /* join via dsp (if the channels are currently open) */ ast_mutex_lock(&chan_lock); - bridge_id = new_bridge_id(); call1 = ast1->tech_pvt; call2 = ast2->tech_pvt; - if (call1 && call2) - { + if (!call1 || !call2) { + CDEBUG(NULL, NULL, "Bridge, but we don't have two call instances, exitting.\n"); + ast_mutex_unlock(&chan_lock); + return AST_BRIDGE_COMPLETE; + } + + /* join, if both call instances uses dsp */ + if (!call1->nodsp && !call2->nodsp) { + CDEBUG(NULL, NULL, "Both calls use DSP, briding via DSP.\n"); + + /* get bridge id and join */ + bridge_id = new_bridge_id(); + call1->bridge_id = bridge_id; if (call1->bchannel) bchannel_join(call1->bchannel, bridge_id); - call1->bridge_call = call2; - } - if (call2) - { + call2->bridge_id = bridge_id; if (call2->bchannel) bchannel_join(call2->bchannel, bridge_id); - call2->bridge_call = call1; - } + } else + if (call1->nodsp && call2->nodsp) + CDEBUG(NULL, NULL, "Both calls use no DSP, briding in channel driver.\n"); + else + CDEBUG(NULL, NULL, "One call uses no DSP, briding in channel driver.\n"); + call1->bridge_call = call2; + call2->bridge_call = call1; if (call1->state == CHAN_LCR_STATE_IN_SETUP || call1->state == CHAN_LCR_STATE_IN_DIALING @@ -2241,24 +2254,24 @@ enum ast_bridge_result lcr_bridge(struct ast_channel *ast1, ast_mutex_lock(&chan_lock); call1 = ast1->tech_pvt; call2 = ast2->tech_pvt; - if (call1) + if (call1 && call1->bridge_id) { call1->bridge_id = 0; if (call1->bchannel) bchannel_join(call1->bchannel, 0); if (call1->bridge_call) call1->bridge_call->bridge_call = NULL; - call1->bridge_call = NULL; } - if (call2) + if (call2 && call1->bridge_id) { call2->bridge_id = 0; if (call2->bchannel) bchannel_join(call2->bchannel, 0); if (call2->bridge_call) call2->bridge_call->bridge_call = NULL; - call2->bridge_call = NULL; } + call1->bridge_call = NULL; + call2->bridge_call = NULL; ast_mutex_unlock(&chan_lock); return AST_BRIDGE_COMPLETE;