diff options
32 files changed, 276 insertions, 193 deletions
@@ -511,7 +511,7 @@ else @echo "<!DOCTYPE docs SYSTEM \"appdocsxml.dtd\">" >> $@ @echo "<?xml-stylesheet type=\"text/xsl\" href=\"appdocsxml.xslt\"?>" >> $@ @echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@ - @for x in $(MOD_SUBDIRS); do \ + @for x in $(filter-out third-party,$(MOD_SUBDIRS)); do \ printf "$$x " ; \ for i in `find $$x -name '*.c'`; do \ $(PYTHON) build_tools/get_documentation.py < $$i >> $@ ; \ diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c index ffdbf6721..24cc65c0f 100644 --- a/addons/chan_ooh323.c +++ b/addons/chan_ooh323.c @@ -5053,9 +5053,7 @@ struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p) ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(p->owner),target_context); } p->faxdetected = 1; - if (dfr) { - ast_frfree(dfr); - } + ast_frfree(dfr); return &ast_null_frame; } } diff --git a/addons/ooh323c/src/context.c b/addons/ooh323c/src/context.c index bc3db4387..c1e2003a2 100644 --- a/addons/ooh323c/src/context.c +++ b/addons/ooh323c/src/context.c @@ -164,6 +164,7 @@ OOCTXT* newContext () /* ASN1CRTFREE0 (pctxt); */ ast_free(pctxt); pctxt = 0; + return (pctxt); } pctxt->flags |= ASN1DYNCTXT; } diff --git a/addons/ooh323c/src/memheap.c b/addons/ooh323c/src/memheap.c index 4bcbd7a3d..4020261bb 100644 --- a/addons/ooh323c/src/memheap.c +++ b/addons/ooh323c/src/memheap.c @@ -623,7 +623,7 @@ void memHeapFreePtr (void** ppvMemHeap, void* mem_p) } } } - if (!ISLAST (pElem) && ISFREE (GETNEXT (pElem))) { + if (pElem && !ISLAST (pElem) && ISFREE (GETNEXT (pElem))) { OSMemElemDescr* nextelem_p = GETNEXT (pElem); /* +1 because the OSMemElemDescr has size ONE unit (8 bytes) */ @@ -638,7 +638,7 @@ void memHeapFreePtr (void** ppvMemHeap, void* mem_p) } /* correct the prevOff field of next element */ - if (!ISLAST (pElem)) { + if (pElem && !ISLAST (pElem)) { OSMemElemDescr* nextelem_p = GETNEXT (pElem); pElem_prevOff (nextelem_p) = QOFFSETOF (nextelem_p, pElem); } @@ -686,7 +686,7 @@ static void initNewFreeElement (OSMemBlk* pMemBlk, } pNextElem = GETNEXT (pNewElem); - if (ISFREE (pNextElem)) { + if (pNextElem && ISFREE (pNextElem)) { /* if the next elem is free, then unite them together */ @@ -820,7 +820,7 @@ void* memHeapRealloc (void** ppvMemHeap, void* mem_p, int nbytes_) /* look for free element after pElem */ pNextElem = GETNEXT (pElem); - if (ISFREE (pNextElem)) { + if (pNextElem && ISFREE (pNextElem)) { /* +1 'cos sizeof (OSMemElemDescr) == 1 unit */ sumSize += pElem_nunits (pNextElem) + 1; freeMem++; @@ -1062,7 +1062,7 @@ void memHeapAddRef (void** ppvMemHeap) void memHeapRelease (void** ppvMemHeap) { OSMemHeap** ppMemHeap = (OSMemHeap**)ppvMemHeap; - OSMemHeap* pMemHeap = *ppMemHeap; + OSMemHeap* pMemHeap; if (ppMemHeap != 0 && *ppMemHeap != 0 && --(*ppMemHeap)->refCnt == 0) { OSMemLink* pMemLink, *pMemLink2; @@ -1080,6 +1080,7 @@ void memHeapRelease (void** ppvMemHeap) } if ((*ppMemHeap)->flags & RT_MH_FREEHEAPDESC) { + pMemHeap = *ppMemHeap; ast_mutex_destroy(&pMemHeap->pLock); ast_free(*ppMemHeap); } diff --git a/addons/ooh323c/src/ooCalls.c b/addons/ooh323c/src/ooCalls.c index 3097c6d28..15ab3258f 100644 --- a/addons/ooh323c/src/ooCalls.c +++ b/addons/ooh323c/src/ooCalls.c @@ -805,8 +805,7 @@ int ooAddMediaInfo(OOH323CallData *call, OOMediaInfo mediaInfo) if(!call) { - OOTRACEERR3("Error:Invalid 'call' param for ooAddMediaInfo.(%s, %s)\n", - call->callType, call->callToken); + OOTRACEERR1("Error:Invalid 'call' param for ooAddMediaInfo.\n"); return OO_FAILED; } newMediaInfo = (OOMediaInfo*) memAlloc(call->pctxt, sizeof(OOMediaInfo)); diff --git a/addons/ooh323c/src/ooCapability.c b/addons/ooh323c/src/ooCapability.c index 731478346..0796c46bf 100644 --- a/addons/ooh323c/src/ooCapability.c +++ b/addons/ooh323c/src/ooCapability.c @@ -62,8 +62,6 @@ int ooCapabilityEnableDTMFCISCO /*Dynamic RTP payload type range is from 96 - 127 */ if(dynamicRTPPayloadType >= 96 && dynamicRTPPayloadType <= 127) gcDynamicRTPPayloadType = dynamicRTPPayloadType; - else - call->dtmfcodec = dynamicRTPPayloadType; } else{ call->dtmfmode |= OO_CAP_DTMF_CISCO; @@ -623,8 +621,7 @@ int ooCapabilityAddT38Capability else pctxt = call->pctxt; epCap = (ooH323EpCapability*)memAllocZ(pctxt, sizeof(ooH323EpCapability)); - params = (OOCapParams*) memAlloc(pctxt, sizeof(OOCapParams)); - memset(params, 0 , sizeof(OOCapParams)); + params = (OOCapParams*) memAllocZ(pctxt, sizeof(OOCapParams)); if(!epCap || !params) { OOTRACEERR1("ERROR: Memory - ooCapabilityAddT38Capability - " @@ -808,8 +805,7 @@ void* ooCapabilityCreateDTMFCapability(int cap, int dtmfcodec, OOCTXT *pctxt) } memset(pATECap, 0, sizeof(H245AudioTelephonyEventCapability)); pATECap->dynamicRTPPayloadType = dtmfcodec; - events = (char*)memAlloc(pctxt, strlen("0-16")+1); - memset(events, 0, strlen("0-16")+1); + events = (char*)memAllocZ(pctxt, strlen("0-16")+1); if(!events) { OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - events\n"); diff --git a/addons/ooh323c/src/ooGkClient.c b/addons/ooh323c/src/ooGkClient.c index a307f4eef..0168ee7de 100644 --- a/addons/ooh323c/src/ooGkClient.c +++ b/addons/ooh323c/src/ooGkClient.c @@ -2332,9 +2332,8 @@ int ooGkClientSendIRR pIRR->m.perCallInfoPresent = TRUE; perCallInfo = - (H225InfoRequestResponse_perCallInfo_element *)memAlloc(pctxt, + (H225InfoRequestResponse_perCallInfo_element *)memAllocZ(pctxt, sizeof(H225InfoRequestResponse_perCallInfo_element)); - memset(perCallInfo, 0, sizeof(H225InfoRequestResponse_perCallInfo_element)); if(!perCallInfo) { diff --git a/addons/ooh323c/src/ooh245.c b/addons/ooh323c/src/ooh245.c index adff91790..fe8ff28e0 100644 --- a/addons/ooh323c/src/ooh245.c +++ b/addons/ooh323c/src/ooh245.c @@ -356,7 +356,6 @@ int ooSendTermCapMsg(OOH323CallData *call) /* pctxt = &gH323ep.msgctxt; */ pctxt = call->msgctxt; ph245msg->msgType = OOTerminalCapabilitySet; - memset(request, 0, sizeof(H245RequestMessage)); if(request == NULL) { OOTRACEERR3("ERROR: No memory allocated for request message (%s, %s)\n", @@ -364,6 +363,7 @@ int ooSendTermCapMsg(OOH323CallData *call) return OO_FAILED; } + memset(request, 0, sizeof(H245RequestMessage)); request->t = T_H245RequestMessage_terminalCapabilitySet; request->u.terminalCapabilitySet = (H245TerminalCapabilitySet*) memAlloc(pctxt, sizeof(H245TerminalCapabilitySet)); diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c index 1ca361c2c..01a8e4aaf 100644 --- a/addons/ooh323c/src/ooq931.c +++ b/addons/ooh323c/src/ooq931.c @@ -2439,8 +2439,10 @@ int ooH323HandleCallFwdRequest(OOH323CallData *call) alias = call->pCallFwdData->aliases; while(alias) { - pNewAlias = (ooAliases*) memAlloc(pctxt, sizeof(ooAliases)); - pNewAlias->value = (char*) memAlloc(pctxt, strlen(alias->value)+1); + pNewAlias = (ooAliases*) memAllocZ(pctxt, sizeof(ooAliases)); + if (pNewAlias) { + pNewAlias->value = (char*) memAllocZ(pctxt, strlen(alias->value)+1); + } if(!pNewAlias || !pNewAlias->value) { OOTRACEERR3("Error:Memory - ooH323HandleCallFwdRequest - " diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index c143e39e2..873831911 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -1673,8 +1673,10 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e, ast_cli(a->fd,"Registration context: %s\n", b_profile.regcontext); switch (b_profile.flags - & (BRIDGE_OPT_VIDEO_SRC_LAST_MARKED | BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED - | BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) { + & (BRIDGE_OPT_VIDEO_SRC_LAST_MARKED | + BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED | + BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER | + BRIDGE_OPT_VIDEO_SRC_SFU)) { case BRIDGE_OPT_VIDEO_SRC_LAST_MARKED: ast_cli(a->fd, "Video Mode: last_marked\n"); break; @@ -1684,6 +1686,9 @@ static char *handle_cli_confbridge_show_bridge_profile(struct ast_cli_entry *e, case BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER: ast_cli(a->fd, "Video Mode: follow_talker\n"); break; + case BRIDGE_OPT_VIDEO_SRC_SFU: + ast_cli(a->fd, "Video Mode: sfu\n"); + break; case 0: ast_cli(a->fd, "Video Mode: no video\n"); break; @@ -2030,12 +2035,6 @@ static int video_mode_handler(const struct aco_option *opt, struct ast_variable | BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER | BRIDGE_OPT_VIDEO_SRC_SFU, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER); - } else if (!strcasecmp(var->value, "none")) { - ast_clear_flag(b_profile, - BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED - | BRIDGE_OPT_VIDEO_SRC_LAST_MARKED - | BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER - | BRIDGE_OPT_VIDEO_SRC_SFU); } else if (!strcasecmp(var->value, "sfu")) { ast_set_flags_to(b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED @@ -2043,6 +2042,12 @@ static int video_mode_handler(const struct aco_option *opt, struct ast_variable | BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER | BRIDGE_OPT_VIDEO_SRC_SFU, BRIDGE_OPT_VIDEO_SRC_SFU); + } else if (!strcasecmp(var->value, "none")) { + ast_clear_flag(b_profile, + BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED + | BRIDGE_OPT_VIDEO_SRC_LAST_MARKED + | BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER + | BRIDGE_OPT_VIDEO_SRC_SFU); } else { return -1; } diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c index f0a3fb42d..ed88b7cd5 100644 --- a/bridges/bridge_softmix.c +++ b/bridges/bridge_softmix.c @@ -1318,6 +1318,12 @@ static void remb_collect_report(struct ast_bridge *bridge, struct ast_bridge_cha break; } } + + /* After the report is integrated we reset this to 0 in case they stop producing + * REMB reports. + */ + sc->remb.br_mantissa = 0; + sc->remb.br_exp = 0; } static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct softmix_channel *sc) @@ -1328,20 +1334,18 @@ static void remb_send_report(struct ast_bridge_channel *bridge_channel, struct s return; } - /* If we have a new bitrate then use it for the REMB, if not we use the previous - * one until we know otherwise. This way the bitrate doesn't drop to 0 all of a sudden. + /* We always do this calculation as even when the bitrate is zero the browser + * still prefers it to be accurate instead of lying. */ - if (sc->remb_collector->bitrate) { - sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->bitrate; - sc->remb_collector->feedback.remb.br_exp = 0; + sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->bitrate; + sc->remb_collector->feedback.remb.br_exp = 0; - /* The mantissa only has 18 bits available, so while it exceeds them we bump - * up the exp. - */ - while (sc->remb_collector->feedback.remb.br_mantissa > 0x3ffff) { - sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->feedback.remb.br_mantissa >> 1; - sc->remb_collector->feedback.remb.br_exp++; - } + /* The mantissa only has 18 bits available, so while it exceeds them we bump + * up the exp. + */ + while (sc->remb_collector->feedback.remb.br_mantissa > 0x3ffff) { + sc->remb_collector->feedback.remb.br_mantissa = sc->remb_collector->feedback.remb.br_mantissa >> 1; + sc->remb_collector->feedback.remb.br_exp++; } for (i = 0; i < AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge); ++i) { @@ -2062,6 +2066,7 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st struct ast_bridge_channel *participant; struct ast_vector_int media_types; int nths[AST_MEDIA_TYPE_END] = {0}; + int idx; switch (bridge->softmix.video_mode.mode) { case AST_BRIDGE_VIDEO_MODE_NONE: @@ -2080,7 +2085,10 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st * When channels end up getting added back in they'll reuse their existing * collector and won't need to allocate a new one (unless they were just added). */ - AST_VECTOR_RESET(&softmix_data->remb_collectors, ao2_cleanup); + for (idx = 0; idx < AST_VECTOR_SIZE(&softmix_data->remb_collectors); ++idx) { + ao2_cleanup(AST_VECTOR_GET(&softmix_data->remb_collectors, idx)); + AST_VECTOR_REPLACE(&softmix_data->remb_collectors, idx, NULL); + } /* First traversal: re-initialize all of the participants' stream maps */ AST_LIST_TRAVERSE(&bridge->channels, participant, entry) { diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc index 1736cc6b2..7fdb9edb7 100644 --- a/channels/chan_vpb.cc +++ b/channels/chan_vpb.cc @@ -108,7 +108,6 @@ extern "C" { #endif /**/ -static const char desc[] = "VoiceTronix V6PCI/V12PCI/V4PCI API Support"; static const char tdesc[] = "Standard VoiceTronix API Driver"; static const char config[] = "vpb.conf"; @@ -360,71 +359,71 @@ static int vpb_indicate(struct ast_channel *ast, int condition, const void *data static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static struct ast_channel_tech vpb_tech = { - type: "vpb", - description: tdesc, - capabilities: NULL, - properties: 0, - requester: vpb_request, - requester_with_stream_topology: NULL, - devicestate: NULL, - presencestate: NULL, - send_digit_begin: vpb_digit_begin, - send_digit_end: vpb_digit_end, - call: vpb_call, - hangup: vpb_hangup, - answer: vpb_answer, - read: vpb_read, - read_stream: NULL, - write: vpb_write, - write_stream: NULL, - send_text: NULL, - send_image: NULL, - send_html: NULL, - exception: NULL, - early_bridge: NULL, - indicate: vpb_indicate, - fixup: vpb_fixup, - setoption: NULL, - queryoption: NULL, - transfer: NULL, - write_video: NULL, - write_text: NULL, - func_channel_read: NULL, - func_channel_write: NULL, + .type = "vpb", + .description = tdesc, + .capabilities = NULL, + .properties = 0, + .requester = vpb_request, + .requester_with_stream_topology = NULL, + .devicestate = NULL, + .presencestate = NULL, + .send_digit_begin = vpb_digit_begin, + .send_digit_end = vpb_digit_end, + .call = vpb_call, + .hangup = vpb_hangup, + .answer = vpb_answer, + .read = vpb_read, + .read_stream = NULL, + .write = vpb_write, + .write_stream = NULL, + .send_text = NULL, + .send_image = NULL, + .send_html = NULL, + .exception = NULL, + .early_bridge = NULL, + .indicate = vpb_indicate, + .fixup = vpb_fixup, + .setoption = NULL, + .queryoption = NULL, + .transfer = NULL, + .write_video = NULL, + .write_text = NULL, + .func_channel_read = NULL, + .func_channel_write = NULL, }; static struct ast_channel_tech vpb_tech_indicate = { - type: "vpb", - description: tdesc, - capabilities: NULL, - properties: 0, - requester: vpb_request, - requester_with_stream_topology: NULL, - devicestate: NULL, - presencestate: NULL, - send_digit_begin: vpb_digit_begin, - send_digit_end: vpb_digit_end, - call: vpb_call, - hangup: vpb_hangup, - answer: vpb_answer, - read: vpb_read, - read_stream: NULL, - write: vpb_write, - write_stream: NULL, - send_text: NULL, - send_image: NULL, - send_html: NULL, - exception: NULL, - early_bridge: NULL, - indicate: NULL, - fixup: vpb_fixup, - setoption: NULL, - queryoption: NULL, - transfer: NULL, - write_video: NULL, - write_text: NULL, - func_channel_read: NULL, - func_channel_write: NULL, + .type = "vpb", + .description = tdesc, + .capabilities = NULL, + .properties = 0, + .requester = vpb_request, + .requester_with_stream_topology = NULL, + .devicestate = NULL, + .presencestate = NULL, + .send_digit_begin = vpb_digit_begin, + .send_digit_end = vpb_digit_end, + .call = vpb_call, + .hangup = vpb_hangup, + .answer = vpb_answer, + .read = vpb_read, + .read_stream = NULL, + .write = vpb_write, + .write_stream = NULL, + .send_text = NULL, + .send_image = NULL, + .send_html = NULL, + .exception = NULL, + .early_bridge = NULL, + .indicate = NULL, + .fixup = vpb_fixup, + .setoption = NULL, + .queryoption = NULL, + .transfer = NULL, + .write_video = NULL, + .write_text = NULL, + .func_channel_read = NULL, + .func_channel_write = NULL, }; #if defined(VPB_NATIVE_BRIDGING) diff --git a/contrib/scripts/refcounter.py b/contrib/scripts/refcounter.py index 1f4b37517..de3cda051 100755 --- a/contrib/scripts/refcounter.py +++ b/contrib/scripts/refcounter.py @@ -18,6 +18,7 @@ Matt Jordan <mjordan@digium.com> """ +from __future__ import print_function import sys import os @@ -35,8 +36,8 @@ def parse_line(line): """ tokens = line.strip().split(',', 7) if len(tokens) < 8: - print "ERROR: ref debug line '%s' contains fewer tokens than " \ - "expected: %d" % (line.strip(), len(tokens)) + print("ERROR: ref debug line '%s' contains fewer tokens than " + "expected: %d" % (line.strip(), len(tokens))) return None processed_line = {'addr': tokens[0], @@ -142,7 +143,7 @@ def process_file(options): del current_objects[obj] if options.leaks: - for key, lines in current_objects.iteritems(): + for (key, lines) in current_objects.items(): leaked_objects.append((key, lines)) return (finished_objects, invalid_objects, leaked_objects, skewed_objects) @@ -156,13 +157,13 @@ def print_objects(objects, prefix=""): this object """ - print "======== %s Objects ========" % prefix - print "\n" + print("======== %s Objects ========" % prefix) + print("\n") for obj in objects: - print "==== %s Object %s history ====" % (prefix, obj[0]) + print("==== %s Object %s history ====" % (prefix, obj[0])) for line in obj[1]['log']: - print line - print "\n" + print(line) + print("\n") def main(argv=None): @@ -198,11 +199,11 @@ def main(argv=None): if not options.invalid and not options.leaks and not options.normal \ and not options.skewed: - print >>sys.stderr, "All options disabled" + print("All options disabled", file=sys.stderr) return -1 if not os.path.isfile(options.filepath): - print >>sys.stderr, "File not found: %s" % options.filepath + print("File not found: %s" % options.filepath, file=sys.stderr) return -1 try: @@ -227,7 +228,7 @@ def main(argv=None): print_objects(finished_objects, "Finalized") except (KeyboardInterrupt, SystemExit, IOError): - print >>sys.stderr, "File processing cancelled" + print("File processing cancelled", file=sys.stderr) return -1 return ret_code diff --git a/contrib/scripts/spandspflow2pcap.py b/contrib/scripts/spandspflow2pcap.py index a6546b693..7c403f105 100755 --- a/contrib/scripts/spandspflow2pcap.py +++ b/contrib/scripts/spandspflow2pcap.py @@ -119,7 +119,7 @@ class FaxPcap(object): else: self.date += timedelta(microseconds=9000) - print seqno, '\t', self.date + self.dateoff + print(seqno, '\t', self.date + self.dateoff) # Make packet. packet, prev_data = self.data2packet(self.date + self.dateoff, diff --git a/contrib/scripts/voicemailpwcheck.py b/contrib/scripts/voicemailpwcheck.py index d7a66d4b9..452255c35 100755 --- a/contrib/scripts/voicemailpwcheck.py +++ b/contrib/scripts/voicemailpwcheck.py @@ -46,20 +46,20 @@ mailbox, context, old_pw, new_pw = sys.argv[1:5] # Enforce a password length of at least 6 characters if len(new_pw) < REQUIRED_LENGTH: - print "INVALID: Password is too short (%d) - must be at least %d" % \ - (len(new_pw), REQUIRED_LENGTH) + print("INVALID: Password is too short (%d) - must be at least %d" % \ + (len(new_pw), REQUIRED_LENGTH)) sys.exit(0) for regex, error in REGEX_BLACKLIST: if re.search(regex, new_pw): - print "INVALID: %s" % error + print("INVALID: %s" % error) sys.exit(0) for pw in PW_BLACKLIST: if new_pw.find(pw) != -1: - print "INVALID: %s is forbidden in a password" % pw + print("INVALID: %s is forbidden in a password" % pw) sys.exit(0) -print "VALID" +print("VALID") sys.exit(0) diff --git a/doc/.gitignore b/doc/.gitignore index 3461c58c5..49bfe4293 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,5 @@ core-en_US.xml +full-en_US.xml rest-api api asterisk-ng-doxygen diff --git a/formats/format_pcm.c b/formats/format_pcm.c index 35612c964..4e846d7cf 100644 --- a/formats/format_pcm.c +++ b/formats/format_pcm.c @@ -91,10 +91,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext) return NULL; } s->fr.datalen = res; - if (ast_format_cmp(s->fmt->format, ast_format_g722) == AST_FORMAT_CMP_EQUAL) - *whennext = s->fr.samples = res * 2; - else - *whennext = s->fr.samples = res; + *whennext = s->fr.samples = res; return &s->fr; } @@ -410,16 +407,11 @@ static int au_rewrite(struct ast_filestream *s, const char *comment) static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence) { off_t min, max, cur; - long offset = 0, bytes; + long offset = 0; struct au_desc *desc = fs->_private; min = desc->hdr_size; - if (ast_format_cmp(fs->fmt->format, ast_format_g722) == AST_FORMAT_CMP_EQUAL) - bytes = sample_offset / 2; - else - bytes = sample_offset; - if ((cur = ftello(fs->f)) < 0) { ast_log(AST_LOG_WARNING, "Unable to determine current position in au filestream %p: %s\n", fs, strerror(errno)); return -1; @@ -436,11 +428,11 @@ static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence) } if (whence == SEEK_SET) - offset = bytes + min; + offset = sample_offset + min; else if (whence == SEEK_CUR || whence == SEEK_FORCECUR) - offset = bytes + cur; + offset = sample_offset + cur; else if (whence == SEEK_END) - offset = max - bytes; + offset = max - sample_offset; if (whence != SEEK_FORCECUR) { offset = (offset > max) ? max : offset; @@ -479,6 +471,23 @@ static off_t au_tell(struct ast_filestream *fs) return offset - desc->hdr_size; } +static struct ast_frame *g722_read(struct ast_filestream *s, int *whennext) +{ + struct ast_frame *f = pcm_read(s, whennext); + *whennext = s->fr.samples = (*whennext * 2); + return f; +} + +static int g722_seek(struct ast_filestream *fs, off_t sample_offset, int whence) +{ + return pcm_seek(fs, sample_offset / 2, whence); +} + +static off_t g722_tell(struct ast_filestream *fs) +{ + return pcm_tell(fs) * 2; +} + static struct ast_format_def alaw_f = { .name = "alaw", .exts = "alaw|al|alw", @@ -510,10 +519,10 @@ static struct ast_format_def g722_f = { .name = "g722", .exts = "g722", .write = pcm_write, - .seek = pcm_seek, + .seek = g722_seek, .trunc = pcm_trunc, - .tell = pcm_tell, - .read = pcm_read, + .tell = g722_tell, + .read = g722_read, .buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET, }; diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 092bb8420..d2ae39baf 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -258,6 +258,14 @@ struct ast_sip_contact { AST_STRING_FIELD(user_agent); /*! The name of the aor this contact belongs to */ AST_STRING_FIELD(aor); + /*! Asterisk Server name */ + AST_STRING_FIELD(reg_server); + /*! IP-address of the Via header in REGISTER request */ + AST_STRING_FIELD(via_addr); + /*! Content of the Call-ID header in REGISTER request */ + AST_STRING_FIELD(call_id); + /*! The name of the endpoint that added the contact */ + AST_STRING_FIELD(endpoint_name); ); /*! Absolute time that this contact is no longer valid after */ struct timeval expiration_time; @@ -269,16 +277,8 @@ struct ast_sip_contact { double qualify_timeout; /*! Endpoint that added the contact, only available in observers */ struct ast_sip_endpoint *endpoint; - /*! Asterisk Server name */ - AST_STRING_FIELD_EXTENDED(reg_server); - /*! IP-address of the Via header in REGISTER request */ - AST_STRING_FIELD_EXTENDED(via_addr); - /* Port of the Via header in REGISTER request */ + /*! Port of the Via header in REGISTER request */ int via_port; - /*! Content of the Call-ID header in REGISTER request */ - AST_STRING_FIELD_EXTENDED(call_id); - /*! The name of the endpoint that added the contact */ - AST_STRING_FIELD_EXTENDED(endpoint_name); /*! If true delete the contact on Asterisk restart/boot */ int prune_on_boot; }; @@ -751,6 +751,8 @@ struct ast_sip_endpoint { AST_STRING_FIELD(message_context); /*! Accountcode to auto-set on channels */ AST_STRING_FIELD(accountcode); + /*! If set, we'll push incoming MWI NOTIFYs to stasis using this mailbox */ + AST_STRING_FIELD(incoming_mwi_mailbox); ); /*! Configuration for extensions */ struct ast_sip_endpoint_extensions extensions; @@ -812,8 +814,6 @@ struct ast_sip_endpoint { unsigned int refer_blind_progress; /*! Whether to notifies dialog-info 'early' on INUSE && RINGING state */ unsigned int notify_early_inuse_ringing; - /*! If set, we'll push incoming MWI NOTIFYs to stasis using this mailbox */ - AST_STRING_FIELD_EXTENDED(incoming_mwi_mailbox); }; /*! URI parameter for symmetric transport */ diff --git a/include/asterisk/stasis_bridges.h b/include/asterisk/stasis_bridges.h index 05d356cc2..a455a5b02 100644 --- a/include/asterisk/stasis_bridges.h +++ b/include/asterisk/stasis_bridges.h @@ -46,6 +46,8 @@ struct ast_bridge_snapshot { AST_STRING_FIELD(creator); /*! Name given to the bridge by its creator */ AST_STRING_FIELD(name); + /*! Unique ID of the channel providing video, if one exists */ + AST_STRING_FIELD(video_source_id); ); /*! AO2 container of bare channel uniqueid strings participating in the bridge. * Allocated from ast_str_container_alloc() */ @@ -60,8 +62,6 @@ struct ast_bridge_snapshot { unsigned int num_active; /*! The video mode of the bridge */ enum ast_bridge_video_mode_type video_mode; - /*! Unique ID of the channel providing video, if one exists */ - AST_STRING_FIELD_EXTENDED(video_source_id); }; /*! diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c index 4b68559de..59b9685ef 100644 --- a/main/stasis_bridges.c +++ b/main/stasis_bridges.c @@ -246,8 +246,7 @@ struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge return NULL; } - if (ast_string_field_init(snapshot, 128) - || ast_string_field_init_extended(snapshot, video_source_id)) { + if (ast_string_field_init(snapshot, 128)) { ao2_ref(snapshot, -1); return NULL; diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 22da80577..6e79dc40b 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -133,11 +133,6 @@ static void *contact_alloc(const char *name) return NULL; } - ast_string_field_init_extended(contact, endpoint_name); - ast_string_field_init_extended(contact, reg_server); - ast_string_field_init_extended(contact, via_addr); - ast_string_field_init_extended(contact, call_id); - /* Dynamic contacts are delimited with ";@" and static ones with "@@" */ if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) { *aor_separator = '\0'; diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 3094f248e..fb84a1f60 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -2248,8 +2248,6 @@ void *ast_sip_endpoint_alloc(const char *name) return NULL; } - ast_string_field_init_extended(endpoint, incoming_mwi_mailbox); - if (!(endpoint->media.codecs = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { ao2_cleanup(endpoint); return NULL; diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index 8a90849c0..0d815ad39 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -834,6 +834,8 @@ static int reregister_immediately_cb(void *obj) * * \param obj What is needed to initiate a reregister attempt. * + * \note Normally executed by the pjsip monitor thread. + * * \return Nothing */ static void registration_transport_shutdown_cb(void *obj) diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c index 9e0718f51..d98491495 100644 --- a/res/res_pjsip_pubsub.c +++ b/res/res_pjsip_pubsub.c @@ -560,15 +560,52 @@ static void *publication_resource_alloc(const char *name) return ast_sorcery_generic_alloc(sizeof(struct ast_sip_publication_resource), publication_resource_destroy); } -static void sub_tree_transport_cb(void *data) { +static int sub_tree_subscription_terminate_cb(void *data) +{ struct sip_subscription_tree *sub_tree = data; - ast_debug(3, "Transport destroyed. Removing subscription '%s->%s' prune on restart: %d\n", + if (!sub_tree->evsub) { + /* Something else already terminated the subscription. */ + ao2_ref(sub_tree, -1); + return 0; + } + + ast_debug(3, "Transport destroyed. Removing subscription '%s->%s' prune on boot: %d\n", sub_tree->persistence->endpoint, sub_tree->root->resource, sub_tree->persistence->prune_on_boot); sub_tree->state = SIP_SUB_TREE_TERMINATE_IN_PROGRESS; pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE); + + ao2_ref(sub_tree, -1); + return 0; +} + +/*! + * \internal + * \brief The reliable transport we used as a subscription contact has shutdown. + * + * \param data What subscription needs to be terminated. + * + * \note Normally executed by the pjsip monitor thread. + * + * \return Nothing + */ +static void sub_tree_transport_cb(void *data) +{ + struct sip_subscription_tree *sub_tree = data; + + /* + * Push off the subscription termination to the serializer to + * avoid deadlock. Another thread could be trying to send a + * message on the subscription that can deadlock with this + * thread. + */ + ao2_ref(sub_tree, +1); + if (ast_sip_push_task(sub_tree->serializer, sub_tree_subscription_terminate_cb, + sub_tree)) { + ao2_ref(sub_tree, -1); + } } /*! \brief Destructor for subscription persistence */ @@ -621,7 +658,7 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr return; } - ast_debug(3, "Updating persistence for '%s->%s' prune on restart: %s\n", + ast_debug(3, "Updating persistence for '%s->%s' prune on boot: %s\n", sub_tree->persistence->endpoint, sub_tree->root->resource, sub_tree->persistence->prune_on_boot ? "yes" : "no"); @@ -645,7 +682,7 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr sub_tree->endpoint, rdata); if (sub_tree->persistence->prune_on_boot) { - ast_debug(3, "adding transport monitor on %s for '%s->%s' prune on restart: %d\n", + ast_debug(3, "adding transport monitor on %s for '%s->%s' prune on boot: %d\n", rdata->tp_info.transport->obj_name, sub_tree->persistence->endpoint, sub_tree->root->resource, sub_tree->persistence->prune_on_boot); diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c index bdee91fb3..985933e2d 100644 --- a/res/res_pjsip_registrar.c +++ b/res/res_pjsip_registrar.c @@ -337,7 +337,7 @@ static int contact_transport_monitor_matcher(void *a, void *b) && strcmp(ma->contact_name, mb->contact_name) == 0; } -static void register_contact_transport_shutdown_cb(void *data) +static int register_contact_transport_remove_cb(void *data) { struct contact_transport_monitor *monitor = data; struct ast_sip_contact *contact; @@ -345,7 +345,8 @@ static void register_contact_transport_shutdown_cb(void *data) aor = ast_sip_location_retrieve_aor(monitor->aor_name); if (!aor) { - return; + ao2_ref(monitor, -1); + return 0; } ao2_lock(aor); @@ -365,6 +366,35 @@ static void register_contact_transport_shutdown_cb(void *data) } ao2_unlock(aor); ao2_ref(aor, -1); + + ao2_ref(monitor, -1); + return 0; +} + +/*! + * \internal + * \brief The reliable transport we registered as a contact has shutdown. + * + * \param data What contact needs to be removed. + * + * \note Normally executed by the pjsip monitor thread. + * + * \return Nothing + */ +static void register_contact_transport_shutdown_cb(void *data) +{ + struct contact_transport_monitor *monitor = data; + + /* + * Push off to a default serializer. This is in case sorcery + * does database accesses for contacts. Database accesses may + * not be on this machine. We don't want to tie up the pjsip + * monitor thread with potentially long access times. + */ + ao2_ref(monitor, +1); + if (ast_sip_push_task(NULL, register_contact_transport_remove_cb, monitor)) { + ao2_ref(monitor, -1); + } } AST_VECTOR(excess_contact_vector, struct ast_sip_contact *); diff --git a/rest-api-templates/api.wiki.mustache b/rest-api-templates/api.wiki.mustache index ad12bb695..a51c3e6ce 100644 --- a/rest-api-templates/api.wiki.mustache +++ b/rest-api-templates/api.wiki.mustache @@ -5,7 +5,7 @@ h1. {{name_title}} {{#apis}} {{#operations}} -| {{http_method}} | [{{wiki_path}}|#{{nickname}}] | {{#response_class}}{{#is_primitive}}{{name}}{{/is_primitive}}{{^is_primitive}}[{{wiki_name}}|{{wiki_prefix}} REST Data Models#{{singular_name}}]{{/is_primitive}}{{/response_class}} | {{summary}} | +| {{http_method}} | [{{wiki_path}}|#{{nickname}}] | {{#response_class}}{{#is_primitive}}{{name}}{{/is_primitive}}{{^is_primitive}}[{{wiki_name}}|{{wiki_prefix}} REST Data Models#{{singular_name}}]{{/is_primitive}}{{/response_class}} | {{{summary}}} | {{/operations}} {{/apis}} {{#apis}} diff --git a/rest-api-templates/ari_resource.h.mustache b/rest-api-templates/ari_resource.h.mustache index df075af35..c1d880d30 100644 --- a/rest-api-templates/ari_resource.h.mustache +++ b/rest-api-templates/ari_resource.h.mustache @@ -76,7 +76,7 @@ int ast_ari_{{c_name}}_{{c_nickname}}_parse_body( {{/parse_body}} /*! - * \brief {{summary}} + * \brief {{{summary}}} {{#notes}} * * {{{notes}}} @@ -99,7 +99,7 @@ void ast_ari_{{c_name}}_{{c_nickname}}(struct ast_tcptls_session_instance *ser, {{#is_websocket}} /*! - * \brief {{summary}} + * \brief {{{summary}}} {{#notes}} * * {{{notes}}} @@ -111,7 +111,7 @@ void ast_ari_{{c_name}}_{{c_nickname}}(struct ast_tcptls_session_instance *ser, int ast_ari_websocket_{{c_name}}_{{c_nickname}}_init(void); /*! - * \brief {{summary}} + * \brief {{{summary}}} {{#notes}} * * {{{notes}}} diff --git a/rest-api-templates/asterisk_processor.py b/rest-api-templates/asterisk_processor.py index 981294673..5f8dbb576 100644 --- a/rest-api-templates/asterisk_processor.py +++ b/rest-api-templates/asterisk_processor.py @@ -23,7 +23,7 @@ Asterisk RESTful HTTP binding code. import os import re -from swagger_model import * +from swagger_model import Stringify, SwaggerError, SwaggerPostProcessor try: from collections import OrderedDict @@ -183,7 +183,7 @@ class AsteriskProcessor(SwaggerPostProcessor): raise SwaggerError( "Should not mix resources in one API declaration", context) # root_path isn't needed any more - resource_api.root_path = resource_api.root_path.children()[0] + resource_api.root_path = list(resource_api.root_path.children())[0] if resource_api.name != resource_api.root_path.name: raise SwaggerError( "API declaration name should match", context) @@ -206,10 +206,10 @@ class AsteriskProcessor(SwaggerPostProcessor): def process_parameter(self, parameter, context): if parameter.param_type == 'body': - parameter.is_body_parameter = True; + parameter.is_body_parameter = True; parameter.c_data_type = 'struct ast_json *' else: - parameter.is_body_parameter = False; + parameter.is_body_parameter = False; if not parameter.data_type in self.type_mapping: raise SwaggerError( "Invalid parameter type %s" % parameter.data_type, context) diff --git a/rest-api-templates/make_ari_stubs.py b/rest-api-templates/make_ari_stubs.py index 0aba06d6d..a25773df4 100755 --- a/rest-api-templates/make_ari_stubs.py +++ b/rest-api-templates/make_ari_stubs.py @@ -16,19 +16,20 @@ # at the top of the source tree. # +from __future__ import print_function import sys try: import pystache except ImportError: - print >> sys.stderr, "Pystache required. Please sudo pip install pystache." + print("Pystache required. Please sudo pip install pystache.", file=sys.stderr) sys.exit(1) import os.path from asterisk_processor import AsteriskProcessor from optparse import OptionParser -from swagger_model import * +from swagger_model import ResourceListing from transform import Transform TOPDIR = os.path.dirname(os.path.abspath(__file__)) diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache index 67a04d898..85948fba1 100644 --- a/rest-api-templates/res_ari_resource.c.mustache +++ b/rest-api-templates/res_ari_resource.c.mustache @@ -55,7 +55,7 @@ #if defined(AST_DEVMODE) #include "ari/ari_model_validators.h" #endif -{{^has_websocket}} +{{#has_websocket}} {{! Only include http_websocket if necessary. Otherwise we'll do a lot of * unnecessary optional_api intialization, which makes optional_api harder * to debug @@ -278,7 +278,7 @@ static int load_module(void) {{#apis}} {{#operations}} -{{#has_websocket}} +{{#is_websocket}} struct ast_websocket_protocol *protocol; if (ast_ari_websocket_{{c_name}}_{{c_nickname}}_init() == -1) { @@ -300,8 +300,6 @@ static int load_module(void) } protocol->session_attempted = ast_ari_{{c_name}}_{{c_nickname}}_ws_attempted_cb; protocol->session_established = ast_ari_{{c_name}}_{{c_nickname}}_ws_established_cb; -{{/has_websocket}} -{{#is_websocket}} res |= ast_websocket_server_add_protocol2({{full_name}}.ws_server, protocol); {{/is_websocket}} {{/operations}} diff --git a/rest-api-templates/swagger_model.py b/rest-api-templates/swagger_model.py index 3f729d8b5..50c5fb07b 100644 --- a/rest-api-templates/swagger_model.py +++ b/rest-api-templates/swagger_model.py @@ -26,6 +26,7 @@ missing, or have incorrect values). See https://github.com/wordnik/swagger-core/wiki/API-Declaration for the spec. """ +from __future__ import print_function import json import os.path import pprint @@ -75,7 +76,7 @@ def compare_versions(lhs, rhs): ''' lhs = [int(v) for v in lhs.split('.')] rhs = [int(v) for v in rhs.split('.')] - return cmp(lhs, rhs) + return (lhs > rhs) - (lhs < rhs) class ParsingContext(object): @@ -444,8 +445,7 @@ class Api(Stringify): op_json = api_json.get('operations') self.operations = [ Operation().load(j, processor, context) for j in op_json] - self.has_websocket = \ - filter(lambda op: op.is_websocket, self.operations) != [] + self.has_websocket = any(op.is_websocket for op in self.operations) processor.process_api(self, context) return self @@ -611,7 +611,7 @@ class ApiDeclaration(Stringify): except SwaggerError: raise except Exception as e: - print >> sys.stderr, "Error: ", traceback.format_exc() + print("Error: ", traceback.format_exc(), file=sys.stderr) raise SwaggerError( "Error loading %s" % api_declaration_file, context, e) @@ -624,8 +624,8 @@ class ApiDeclaration(Stringify): .replace(".json", ".{format}") if self.resource_path != expected_resource_path: - print >> sys.stderr, \ - "%s != %s" % (self.resource_path, expected_resource_path) + print("%s != %s" % (self.resource_path, expected_resource_path), + file=sys.stderr) raise SwaggerError("resourcePath has incorrect value", context) return self @@ -656,8 +656,7 @@ class ApiDeclaration(Stringify): if api.path in paths: raise SwaggerError("API with duplicated path: %s" % api.path, context) paths.add(api.path) - self.has_websocket = filter(lambda api: api.has_websocket, - self.apis) == [] + self.has_websocket = any(api.has_websocket for api in self.apis) models = api_decl_json.get('models').items() or [] self.models = [Model().load(id, json, processor, context) for (id, json) in models] @@ -666,7 +665,7 @@ class ApiDeclaration(Stringify): model_dict = dict((m.id, m) for m in self.models) for m in self.models: def link_subtype(name): - res = model_dict.get(subtype) + res = model_dict.get(name) if not res: raise SwaggerError("%s has non-existing subtype %s", m.id, name) @@ -725,7 +724,7 @@ class ResourceListing(Stringify): except SwaggerError: raise except Exception as e: - print >> sys.stderr, "Error: ", traceback.format_exc() + print("Error: ", traceback.format_exc(), file=sys.stderr) raise SwaggerError( "Error loading %s" % resource_file, context, e) diff --git a/rest-api-templates/transform.py b/rest-api-templates/transform.py index c3a030064..88f7d2e67 100644 --- a/rest-api-templates/transform.py +++ b/rest-api-templates/transform.py @@ -21,6 +21,11 @@ import os.path import pystache import shutil import tempfile +import sys + +if sys.version_info[0] == 3: + def unicode(v): + return str(v) class Transform(object): @@ -52,10 +57,10 @@ class Transform(object): dest_exists = os.path.exists(dest_file) if dest_exists and not self.overwrite: return - with tempfile.NamedTemporaryFile() as out: + with tempfile.NamedTemporaryFile(mode='w+') as out: out.write(renderer.render(self.template, model)) out.flush() if not dest_exists or not filecmp.cmp(out.name, dest_file): - print "Writing %s" % dest_file + print("Writing %s" % dest_file) shutil.copyfile(out.name, dest_file) |