diff -r -u asterisk-1.4.21.1/apps/app_dial.c asterisk-1.4.21.1-X/apps/app_dial.c --- asterisk-1.4.21.1/apps/app_dial.c 2008-06-02 03:03:22.000000000 +0200 +++ asterisk-1.4.21.1-X/apps/app_dial.c 2008-07-10 17:26:02.000000000 +0200 @@ -1230,6 +1230,8 @@ tmp->chan->adsicpe = chan->adsicpe; /* Pass the transfer capability */ tmp->chan->transfercapability = chan->transfercapability; + /* Pass the user information layer 1 */ + tmp->chan->userinformationlayer1 = chan->userinformationlayer1; /* If we have an outbound group, set this peer channel to it */ if (outbound_group) Only in asterisk-1.4.21.1-X/apps: app_dial.c.orig diff -r -u asterisk-1.4.21.1/channels/chan_zap.c asterisk-1.4.21.1-X/channels/chan_zap.c --- asterisk-1.4.21.1/channels/chan_zap.c 2008-06-04 20:35:47.000000000 +0200 +++ asterisk-1.4.21.1-X/channels/chan_zap.c 2008-07-10 17:26:02.000000000 +0200 @@ -331,6 +331,7 @@ int span; int resetting; int resetpos; + int h324musellc; time_t lastreset; /*!< time when unused channels were last reset */ long resetinterval; /*!< Interval (in seconds) for resetting unused channels */ struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */ @@ -619,6 +620,7 @@ .localprefix = "", .privateprefix = "", .unknownprefix = "", + .h324musellc = 0, .resetinterval = 3600 }, @@ -2127,11 +2129,23 @@ else exclusive = 1; } - + + if (p->digital) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "digital call, setting user information layer 1 to %d (0x%x)\n", ast->userinformationlayer1, ast->userinformationlayer1); + } pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1); pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, - (p->digital ? -1 : + (p->digital ? ast->userinformationlayer1 : + ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); + /* check if h324m is configure to use low layer compatibility instead of bearer capability */ +ast_verbose(VERBOSE_PREFIX_3 "zap call: h324musellc=%d, ast->userinformationlayer1=%d\n", p->pri->h324musellc, ast->userinformationlayer1); + if (p->pri->h324musellc && (ast->userinformationlayer1==PRI_LAYER_1_H223_H245)) { + pri_sr_set_llc(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability, + (p->digital ? ast->userinformationlayer1 : ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW))); + } + if (p->pri->facilityenable) pri_facility_enable(p->pri->pri); @@ -3486,7 +3500,7 @@ static void *ss_thread(void *data); -static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int); +static struct ast_channel *zt_new(struct zt_pvt *, int, int, int, int, int, int); static int attempt_transfer(struct zt_pvt *p) { @@ -4266,7 +4280,7 @@ goto winkflashdone; } /* Make new channel */ - chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0); + chan = zt_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, 0, -1); if (p->zaptrcallerid) { if (!p->origcid_num) p->origcid_num = ast_strdup(p->cid_num); @@ -5192,7 +5206,8 @@ return res; } -static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, int transfercapability) +static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int index, int law, + int transfercapability, int userinformationlayer1) { struct ast_channel *tmp; int deflaw; @@ -5236,15 +5251,21 @@ ast_log(LOG_WARNING, "Unable to get parameters, assuming MULAW\n"); ps.curlaw = ZT_LAW_MULAW; } - if (ps.curlaw == ZT_LAW_ALAW) + if (ps.curlaw == ZT_LAW_ALAW) { + ast_log(LOG_DEBUG, "zt_new: ps.curlaw=ZT_LAW_ALAW, setting deflaw to AST_FORMAT_ALAW\n"); deflaw = AST_FORMAT_ALAW; - else + } else { + ast_log(LOG_DEBUG, "zt_new: ps.curlaw!=ZT_LAW_ALAW, setting deflaw to AST_FORMAT_ULAW\n"); deflaw = AST_FORMAT_ULAW; + } if (law) { - if (law == ZT_LAW_ALAW) + if (law == ZT_LAW_ALAW) { + ast_log(LOG_DEBUG, "zt_new: law=ZT_LAW_ALAW, setting deflaw to AST_FORMAT_ALAW\n"); deflaw = AST_FORMAT_ALAW; - else + } else { + ast_log(LOG_DEBUG, "zt_new: law=ZT_LAW_ALAW, setting deflaw to AST_FORMAT_ULAW\n"); deflaw = AST_FORMAT_ULAW; + } } tmp->fds[0] = i->subs[index].zfd; tmp->nativeformats = AST_FORMAT_SLINEAR | deflaw; @@ -5351,6 +5372,7 @@ tmp->cid.cid_ton = i->cid_ton; #ifdef HAVE_PRI tmp->transfercapability = transfercapability; + tmp->userinformationlayer1 = userinformationlayer1; pbx_builtin_setvar_helper(tmp, "TRANSFERCAPABILITY", ast_transfercapability2str(transfercapability)); if (transfercapability & PRI_TRANS_CAP_DIGITAL) i->digital = 1; @@ -6616,7 +6638,7 @@ zt_enable_ec(i); /* The channel is immediately up. Start right away */ res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_RINGTONE); - chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0); + chan = zt_new(i, AST_STATE_RING, 1, SUB_REAL, 0, 0, -1); if (!chan) { ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel); res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); @@ -6625,7 +6647,7 @@ } } else { /* Check for callerid, digits, etc */ - chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0); + chan = zt_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, 0, -1); if (chan) { if (has_voicemail(i)) res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_STUTTER); @@ -6665,7 +6687,7 @@ case SIG_SF_FEATB: case SIG_SF: /* Check for callerid, digits, etc */ - chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0); + chan = zt_new(i, AST_STATE_RING, 0, SUB_REAL, 0, 0, -1); if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION); @@ -6784,7 +6806,7 @@ ast_verbose(VERBOSE_PREFIX_2 "Starting post polarity " "CID detection on channel %d\n", i->channel); - chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0); + chan = zt_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0, -1); if (chan && ast_pthread_create(&threadid, &attr, ss_thread, chan)) { ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel); } @@ -7326,6 +7348,7 @@ pris[span].nsf = conf->pri.nsf; pris[span].dialplan = conf->pri.dialplan; pris[span].localdialplan = conf->pri.localdialplan; + pris[span].h324musellc = conf->pri.h324musellc; pris[span].pvts[pris[span].numchans++] = tmp; pris[span].minunused = conf->pri.minunused; pris[span].minidle = conf->pri.minidle; @@ -7940,7 +7963,7 @@ } } p->outgoing = 1; - tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0); + tmp = zt_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0, -1); #ifdef HAVE_PRI if (p->bearer) { /* Log owner to bearer channel, too */ @@ -8828,13 +8851,20 @@ if (pri->switchtype != PRI_SWITCH_GR303_TMC) { /* Set to audio mode at this point */ law = 1; + ast_log(LOG_DEBUG, "PRI_EVENT_RING: seting incoming call on channel %d to law=%d\n", pri->pvts[chanpos]->channel, law); if (ioctl(pri->pvts[chanpos]->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &law) == -1) ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", pri->pvts[chanpos]->channel, law); } - if (e->ring.layer1 == PRI_LAYER_1_ALAW) + /* note: unknown layer1 will be handled like ULAW (e.g. digital H324M calls) */ + ast_log(LOG_DEBUG, "PRI_EVENT_RING: user information layer 1 of incoming call = %d (0x%x)\n",e->ring.layer1, e->ring.layer1); + if (e->ring.layer1 == PRI_LAYER_1_ALAW) { law = ZT_LAW_ALAW; - else + ast_log(LOG_DEBUG, "PRI_EVENT_RING: treat incoming call on channel %d as ALAW(%d)\n", pri->pvts[chanpos]->channel, law); + } else { law = ZT_LAW_MULAW; + ast_log(LOG_DEBUG, "PRI_EVENT_RING: treat incoming call on channel %d as ULAW(%d)\n", pri->pvts[chanpos]->channel, law); + } + ast_log(LOG_DEBUG, "PRI_EVENT_RING: seting incoming call on channel %d to law=%d\n", pri->pvts[chanpos]->channel, law); res = zt_setlaw(pri->pvts[chanpos]->subs[SUB_REAL].zfd, law); if (res < 0) ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pri->pvts[chanpos]->channel); @@ -8861,11 +8891,11 @@ if (crv) { /* Set bearer and such */ pri_assign_bearer(crv, pri, pri->pvts[chanpos]); - c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); + c = zt_new(crv, AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype, e->ring.layer1); pri->pvts[chanpos]->owner = &inuse; ast_log(LOG_DEBUG, "Started up crv %d:%d on bearer channel %d\n", pri->trunkgroup, crv->channel, crv->bearer->channel); } else { - c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype); + c = zt_new(pri->pvts[chanpos], AST_STATE_RESERVED, 0, SUB_REAL, law, e->ring.ctype, e->ring.layer1); } ast_mutex_unlock(&pri->pvts[chanpos]->lock); @@ -8913,7 +8943,8 @@ } else { ast_mutex_unlock(&pri->lock); /* Release PRI lock while we create the channel */ - c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype); + ast_log(LOG_DEBUG, "PRI_EVENT_RING: zt_new: law=%d,ul1=%d\n",law, e->ring.layer1); + c = zt_new(pri->pvts[chanpos], AST_STATE_RING, 1, SUB_REAL, law, e->ring.ctype, e->ring.layer1); if (c) { char calledtonstr[10]; @@ -10074,6 +10105,10 @@ ast_cli(fd, "PRI Logical Span: %d\n", tmp->logicalspan); else ast_cli(fd, "PRI Logical Span: Implicit\n"); + if (tmp->pri->h324musellc == 1) + ast_cli(fd, "H324M Signalling: use 'Low Layer Compatibility' IE\n"); + else + ast_cli(fd, "H324M Signalling: use 'Bearer Capability' IE\n"); } #endif @@ -11036,6 +11071,16 @@ ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value); return -1; } + } else if (!strcasecmp(v->name, "h324m")) { + if (!strcasecmp(v->value, "bc")) { + confp->pri.h324musellc = 0; + ast_log(LOG_WARNING, "h324m mode: confp->pri.h324musellc=%d\n",confp->pri.h324musellc); + } else if (!strcasecmp(v->value, "llc")) { + confp->pri.h324musellc = 1; + ast_log(LOG_WARNING, "h324m mode: confp->pri.h324musellc=%d\n",confp->pri.h324musellc); + } else { + ast_log(LOG_WARNING, "Unknown h324m mode '%s' at line %d. Using default=bc\n", v->value, v->lineno); + } } else if (!strcasecmp(v->name, "nsf")) { if (!strcasecmp(v->value, "sdn")) confp->pri.nsf = PRI_NSF_SDN; Only in asterisk-1.4.21.1-X/channels: chan_zap.c.orig Only in asterisk-1.4.21.1-X/channels: chan_zap.c.rej diff -r -u asterisk-1.4.21.1/configs/zapata.conf.sample asterisk-1.4.21.1-X/configs/zapata.conf.sample --- asterisk-1.4.21.1/configs/zapata.conf.sample 2008-04-25 17:53:52.000000000 +0200 +++ asterisk-1.4.21.1-X/configs/zapata.conf.sample 2008-07-10 17:26:02.000000000 +0200 @@ -242,6 +242,15 @@ ; usecallerid=yes ; +; H324M signalling. 3G UMTS video calls require to set a certain User Information Layer 1 +; value. The UL1 can be set either in the Bearer Capability Information Element or in the +; Low Layer Compatiblity Information Element. Depending on the switch were your PRI is +; connected to, you need one or the other. +; Allowed values: bc or llc +; Default value: bc +; +;h324m=lcc +; ; Type of caller ID signalling in use ; bell = bell202 as used in US ; v23 = v23 as used in the UK diff -r -u asterisk-1.4.21.1/funcs/func_channel.c asterisk-1.4.21.1-X/funcs/func_channel.c --- asterisk-1.4.21.1/funcs/func_channel.c 2007-03-27 18:20:53.000000000 +0200 +++ asterisk-1.4.21.1-X/funcs/func_channel.c 2008-07-10 17:26:02.000000000 +0200 @@ -88,7 +88,11 @@ locked_copy_string(chan, buf, chan->tech->type, len); else if (!strcasecmp(data, "transfercapability")) locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len); - else if (!strcasecmp(data, "callgroup")) { + else if (!strcasecmp(data, "userinformationlayer1")) { + char ul1[10]; + snprintf(ul1,9,"%d",chan->userinformationlayer1); + locked_copy_string(chan, buf, ul1, len); + } else if (!strcasecmp(data, "callgroup")) { char groupbuf[256]; locked_copy_string(chan, buf, ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len); } else if (!chan->tech->func_channel_read @@ -133,6 +137,8 @@ break; } } + } else if (!strcasecmp(data, "userinformationlayer1")) { + chan->userinformationlayer1 = atoi(value); } else if (!chan->tech->func_channel_write || chan->tech->func_channel_write(chan, function, data, value)) { ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", @@ -158,7 +164,9 @@ "R/W musicclass class (from musiconhold.conf) for hold music\n" "R/W rxgain set rxgain level on channel drivers that support it\n" "R/O state state for channel\n" + "R/W transfercapability ISDN transfer capability (part of ISDN transfer capability)\n" "R/W tonezone zone for indications played\n" + "R/W userinformationlayer1 ISDN User Information Layer 1 (part of ISDN transfer capability)\n" "R/W txgain set txgain level on channel drivers that support it\n" "R/O videonativeformat format used natively for video\n" "\n" diff -r -u asterisk-1.4.21.1/include/asterisk/channel.h asterisk-1.4.21.1-X/include/asterisk/channel.h --- asterisk-1.4.21.1/include/asterisk/channel.h 2008-05-14 23:32:00.000000000 +0200 +++ asterisk-1.4.21.1-X/include/asterisk/channel.h 2008-07-10 17:26:02.000000000 +0200 @@ -434,6 +434,7 @@ ast_group_t pickupgroup; /*!< Pickup group - which calls groups can be picked up? */ unsigned int flags; /*!< channel flags of AST_FLAG_ type */ unsigned short transfercapability; /*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */ + unsigned short userinformationlayer1; /*!< ISDN User Information Layer 1 - transfercapability is not enough */ AST_LIST_HEAD_NOLOCK(, ast_frame) readq; int alertpipe[2]; Only in asterisk-1.4.21.1-X/include/asterisk: channel.h.orig Only in asterisk-1.4.21.1-X/include/asterisk: version.h