--- asterisk-1.4.17/apps/app_dial.c 2007-12-07 17:38:48.000000000 +0100 +++ asterisk-1.4.17-h324m/apps/app_dial.c 2008-01-09 19:15:55.000000000 +0100 @@ -1238,6 +1238,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) --- asterisk-1.4.17/channels/chan_zap.c 2007-12-20 21:08:42.000000000 +0100 +++ asterisk-1.4.17-h324m/channels/chan_zap.c 2008-01-15 11:43:16.000000000 +0100 @@ -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 */ @@ -618,6 +619,7 @@ .localprefix = "", .privateprefix = "", .unknownprefix = "", + .h324musellc = 0, .resetinterval = 3600 }, @@ -2130,11 +2132,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); @@ -3495,7 +3509,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) { @@ -4260,7 +4274,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); @@ -5178,7 +5192,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; @@ -5222,15 +5237,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; @@ -5337,6 +5358,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; @@ -6605,7 +6627,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); @@ -6614,7 +6636,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); @@ -6654,7 +6676,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); @@ -6756,7 +6778,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); } @@ -7303,6 +7325,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; @@ -7897,7 +7920,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 */ @@ -8774,13 +8797,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); @@ -8801,17 +8831,17 @@ pri->pvts[chanpos]->callingpres = e->ring.callingpres; /* Start PBX */ - if (pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { + if (!e->ring.complete && pri->overlapdial && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { /* Release the PRI lock while we create the channel */ ast_mutex_unlock(&pri->lock); 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); @@ -8859,7 +8889,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]; @@ -10008,6 +10039,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 @@ -10970,6 +11005,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; --- asterisk-1.4.17/funcs/func_channel.c 2007-03-27 18:20:53.000000000 +0200 +++ asterisk-1.4.17-h324m/funcs/func_channel.c 2008-01-09 19:15:55.000000000 +0100 @@ -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" --- asterisk-1.4.17/include/asterisk/channel.h 2007-12-04 00:12:17.000000000 +0100 +++ asterisk-1.4.17-h324m/include/asterisk/channel.h 2008-01-09 19:15:55.000000000 +0100 @@ -419,6 +419,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]; --- asterisk-1.4.17/configs/zapata.conf.sample 2007-09-14 23:17:08.000000000 +0200 +++ asterisk-1.4.17-h324m/configs/zapata.conf.sample 2008-01-23 09:12:16.000000000 +0100 @@ -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