In working with res_stasis, I discovered a significant limitation to
the current structure of stasis_caching_topics: you cannot subscribe
to cache updates for a single channel/bridge/endpoint/etc.
To address this, this patch splits the cache away from the
stasis_caching_topic, making it a first class object. The stasis_cache
object is shared amongst individual stasis_caching_topics that are
created per channel/endpoint/etc. These are still forwarded to global
whatever_all_cached topics, so their use from most of the code does
not change.
In making these changes, I noticed that we frequently used a similar
pattern for bridges, endpoints and channels:
single_topic ----------------> all_topic
^
|
single_topic_cached ----+----> all_topic_cached
|
+----> cache
This pattern was extracted as the 'Stasis Caching Pattern', defined in
stasis_caching_pattern.h. This avoids a lot of duplicate code between
the different domain objects.
Since the cache is now disassociated from its upstream caching topics,
this also necessitated a change to how the 'guaranteed' flag worked
for retrieving from a cache. The code for handling the caching
guarantee was extracted into a 'stasis_topic_wait' function, which
works for any stasis_topic.
(closes issue ASTERISK-22002)
Review: https://reviewboard.asterisk.org/r/2672/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395954 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This patch is the first step in adding recording support to the
Asterisk REST Interface.
Recordings are stored in /var/spool/recording. Since recordings may be
destructive (overwriting existing files), the API rejects attempts to
escape the recording directory (avoiding issues if someone attempts to
record to ../../lib/sounds/greeting, for example).
(closes issue ASTERISK-21594)
(closes issue ASTERISK-21581)
Review: https://reviewboard.asterisk.org/r/2612/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393550 65c4cc65-6c06-0410-ace0-fbb531ad65f3
In revision 389733, mwi state allocation was placed into its
own function instead of performing the allocation in-line when
required. The issue was that in ast_publish_mwi_state_full(),
the local variable "uniqueid" was no longer being set, but it was
still being used as the topic for MWI. This meant that all MWI
publications ended up being published to the "" (empty string)
mailbox topic. Thus MWI subscriptions for specific mailboxes were
never notified of mailbox state changes.
This change fixes the issue by removing the local uniqueid variable
from ast_publish_mwi_state_full() and instead referencing the
mwi_state->uniqueid field since it has been properly set.
(closes issue ASTERISK-21913)
Reported by Malcolm Davenport
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391921 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Topics need to be disposed of prior to the message types that are published
on them. This includes topic pools. This prevents an assertion from being
raised on shutdown.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391040 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This patch addresses issues during immediate shutdowns, where modules
are not unloaded, but Asterisk atexit handlers are run.
In the typical case, this usually isn't a big deal. But the
introduction of the Stasis message bus makes it much more likely for
asynchronous activity to be happening off in some thread during
shutdown.
During an immediate shutdown, Asterisk skips unloading modules. But
while it is processing the atexit handlers, there is a window of time
where some of the core message types have been cleaned up, but the
message bus is still running. Specifically, it's still running
module subscriptions that might be using the core message types. If a
message is received by that subscription in that window, it will
attempt to use a message type that has been cleaned up.
To solve this problem, this patch introduces ast_register_cleanup().
This function operates identically to ast_register_atexit(), except
that cleanup calls are not invoked on an immediate shutdown. All of
the core message type and topic cleanup was moved from atexit handlers
to cleanup handlers.
This ensures that core type and topic cleanup only happens if the
modules that used them are first unloaded.
This patch also changes the ast_assert() when accessing a cleaned up
or uninitialized message type to an error log message. Message type
functions are actually NULL safe across the board, so the assert was a
bit heavy handed. Especially for anyone with DO_CRASH enabled.
Review: https://reviewboard.asterisk.org/r/2562/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@390122 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This patch moves a number of AMI events over to the Stasis-Core message bus.
This includes:
* ChanSpyStart/Stop
* MonitorStart/Stop
* MusicOnHoldStart/Stop
* FullyBooted/Reload
* All Voicemail/MWI related events
In addition, it adds some Stasis-Core and AMI support for generic AMI messages,
refactors the message router in AMI to use a single router with topic
forwarding for the topics that AMI cares about, and refactors MWI message
types and topics to be more name compliant.
Review: https://reviewboard.asterisk.org/r/2532
(closes issue ASTERISK-21462)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389733 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Asterisk REST interface.
This adds the /playback/{playbackId}/control resource, which may be
POSTed to to pause, unpause, reverse, forward or restart the media
playback.
Attempts to control a playback that is not currently playing will
either return a 404 Not Found (because the playback object no longer
exists) or a 409 Conflict (because the playback object is still in the
queue to be played).
This patch also adds skipms and offsetms parameters to the
/channels/{channelId}/play resource.
(closes issue ASTERISK-21587)
Review: https://reviewboard.asterisk.org/r/2559
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389603 65c4cc65-6c06-0410-ace0-fbb531ad65f3
The caching topic (which refers to the message type) was created before the
message type. If the initial subscription message gets processed before
the type can be initialized, the assertion about using an uninitialized type
fires.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389519 65c4cc65-6c06-0410-ace0-fbb531ad65f3
In r388005, macros were introduced to consistently define message
types. This added an assert if a message type was used either before
it was initialized or after it had been cleaned up. It turns out that
this assertion fires during shutdown.
This actually exposed a hidden shutdown ordering problem. Since
unsubscribing is asynchronous, it's possible that the message types
used by the subscription could be freed before the final message of
the subscription was processed.
This patch adds stasis_subscription_join(), which blocks until the
last message has been processed by the subscription. Since joining was
most commonly done right after an unsubscribe, a
stasis_unsubscribe_and_join() convenience function was also added.
Similar functions were also added to the stasis_caching_topic and
stasis_message_router, since they wrap subscriptions and have similar
problems.
Other code in trunk was refactored to join() where appropriate, or at
least verify that the subscription was complete before being
destroyed.
Review: https://reviewboard.asterisk.org/r/2540
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389011 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Remove MWI's dependency on the event system by moving it to
Stasis-core. This also introduces forwarding topic pools in Stasis-core
which aggregate many dynamically allocated topics into a single primary
topic.
Review: https://reviewboard.asterisk.org/r/2368/
(closes issue ASTERISK-21097)
Patch-by: Kinsey Moore
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@383284 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This patch adds the capability for asynchronous manipulation of audio being
played back to a channel though a new AMI action "ControlPlayback". The
ControlPlayback action supports a number of operations, the availability of
which depend on the application being used to send audio to the channel.
When the audio playback was initiated using the ControlPlayback application
or CONTROL STREAM FILE AGI command, the audio can be paused, stopped,
restarted, reversed, or skipped forward. When initiated by other mechanisms
(such as the Playback application), the audio can be stopped, reversed, or
skipped forward.
Review: https://reviewboard.asterisk.org/r/2265/
(closes issue ASTERISK-20882)
Reported by: mjordan
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@379830 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Update and extend the configuration_file group and enable linking. Commit other cleanups from multi-version Doxygen testing. Update title that was left behind many years ago.
(issue ASTERISK-20259)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@375182 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Add app_skel.c as an example in app.c and fix some formating for the "Dial Privacy scripts" so it actually shows up in the Doxygen output.
(issue ASTERISK-20259)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@374956 65c4cc65-6c06-0410-ace0-fbb531ad65f3
* The following dialplan applications now recognize 'W' to pause sending
DTMF for one second in addition to the previously existing 'w' that paused
sending DTMF for half a second. Dial, ExternalIVR, and SendDTMF.
* The chan_dahdi analog port dialing and deferred DTMF dialing for PRI now
distinguishes between 'w' and 'W'. The 'w' pauses dialing for half a
second. The 'W' pauses dialing for one second.
* Created dahdi_dial_str() in chan_dahdi that eliminated a lot of
duplicated dialing code and diagnostic messages for the channel driver.
(closes issue ASTERISK-20039)
Reported by: Jeremiah Gowdy
Patches:
jgowdy-wait-6-22-2012.diff (license #5621) patch uploaded by Jeremiah Gowdy
Expanded patch to add support in chan_dahdi.
Tested by: rmudgett
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@374030 65c4cc65-6c06-0410-ace0-fbb531ad65f3
* Made ast_dtmf_stream() wait after starting the silence generator rather
than before.
* Made ast_dtmf_stream() put the peer in autoservice for the whole time
things are being done to the chan.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373966 65c4cc65-6c06-0410-ace0-fbb531ad65f3
........
r369001 | kpfleming | 2012-06-15 10:56:08 -0500 (Fri, 15 Jun 2012) | 11 lines
Add support-level indications to many more source files.
Since we now have tools that scan through the source tree looking for files
with specific support levels, we need to ensure that every file that is
a component of a 'core' or 'extended' module (or the main Asterisk binary)
is explicitly marked with its support level. This patch adds support-level
indications to many more source files in tree, but avoids adding them to
third-party libraries that are included in the tree and to source files
that don't end up involved in Asterisk itself.
........
r369002 | kpfleming | 2012-06-15 10:57:14 -0500 (Fri, 15 Jun 2012) | 3 lines
Add a script to enable finding source files without support-levels defined.
........
Merged revisions 369001-369002 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 369005 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369013 65c4cc65-6c06-0410-ace0-fbb531ad65f3
* Make non-normal dialplan execution routines be able to run on a hung up
channel. This is preparation work for hangup handler routines.
* Fixed ability to support relative non-normal dialplan execution
routines. (i.e., The context and exten are optional for the specified
dialplan location.) Predial routines are the only non-normal routines that
it makes sense to optionally omit the context and exten. Setting a hangup
handler also needs this ability.
* Fix Return application being able to restore a dialplan location
exactly. Channels without a PBX may not have context or exten set.
* Fixes non-normal execution routines like connected line interception and
predial leaving the dialplan execution stack unbalanced. Errors like
missing Return statements, popping too many stack frames using StackPop,
or an application returning non-zero could leave the dialplan stack
unbalanced.
* Fixed the AGI gosub application so it cleans up the dialplan execution
stack and handles the autoloop priority increments correctly.
* Eliminated the need for the gosub_virtual_context return location.
Review: https://reviewboard.asterisk.org/r/1984/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368985 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Presence support has been added. This is accomplished by
allowing for presence hints in addition to device state
hints. A dialplan function called PRESENCE_STATE has been
added to allow for setting and reading presence. Presence
can be transmitted to Digium phones using custom XML
elements in a PIDF presence document.
Voicemail has new APIs that allow for moving, removing,
forwarding, and playing messages. Messages have had a new
unique message ID added to them so that the APIs will work
reliably. The state of a voicemail mailbox can be obtained
using an API that allows one to get a snapshot of the mailbox.
A voicemail Dialplan App called VoiceMailPlayMsg has been
added to be able to play back a specific message.
Configuration hooks have been added. Configuration hooks
allow for a piece of code to be executed when a specific
configuration file is loaded by a specific module. This is
useful for modules that are dependent on the configuration
of other modules.
chan_sip now has a public method that allows for a custom
SIP INFO request to be sent mid-dialog. Digium phones use
this in order to display progress bars when files are played.
Messaging support has been expanded a bit. The main
visible difference is the addition of an AMI action
MessageSend.
Finally, a ParkingLots manager action has been added in order
to get a list of parking lots.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@368435 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This resolves core findings from ASTERISK-19650 numbers 0-2, 6, 7, 9-11, 14-20,
22-24, 28, 30-32, 34-36, 42-56, 82-84, 87, 89-90, 93-102, 104, 105, 109-111,
and 115. Finding numbers 26, 33, and 29 were already resolved. Those skipped
were either extended/deprecated or in areas of code that shouldn't be
disturbed.
(Closes issue ASTERISK-19650)
........
Merged revisions 366167 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 366168 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366169 65c4cc65-6c06-0410-ace0-fbb531ad65f3
* Redo ast_app_run_sub()/ast_app_exec_sub() to use a known return point so
execution will stop after the routine returns there.
(s@gosub_virtual_context:1)
* Create ast_app_exec_macro() and ast_app_exec_sub() to run the macro and
gosub application respectively with the parameter string already created.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@362962 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Everything still compiled after making these changes, so I assume these
whitespace-only changes didn't break anything (and shouldn't have).
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@360190 65c4cc65-6c06-0410-ace0-fbb531ad65f3
* Remove unnnecessary const from const char * const var declaration in the
ast_app_run_macro() and ast_app_run_sub() prototypes. The second const is
unnecessary.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@359904 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit adds GoSub alternatives to connected line, redirecting, and CCSS
macro hooks so that macro can finally be deprecated. This also adds
deprecation warnings for those features when used and in documentation.
Review: https://reviewboard.asterisk.org/r/1760/
(closes issue SWP-4256)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@357013 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Continue channel opaque-ification by wrapping all of the stringfields.
Eventually, we will restrict what can actually set these variables, but
the purpose for now is to hide the implementation and keep people from
adding code that directly accesses the channel structure. Semantic
changes will follow afterward.
Review: https://reviewboard.asterisk.org/r/1661/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@352348 65c4cc65-6c06-0410-ace0-fbb531ad65f3
There are many benefits to making the ast_channel an opaque handle, from
increasing maintainability to presenting ways to kill masquerades. This patch
kicks things off by taking things a field at a time, renaming the field to
'__do_not_use_${fieldname}' and then writing setters/getters and converting the
existing code to using them. When all fields are done, we can move ast_channel
to a C file from channel.h and lop off the '__do_not_use_'.
This patch sets up main/channel_interal_api.c to be the only file that actually
accesses the ast_channel's fields directly. The intent would be for any API
functions in channel.c to use the accessor functions. No more monkeying around
with channel internals. We should use our own APIs.
The interesting changes in this patch are the addition of
channel_internal_api.c, the moving of the AST_DATA stuff from channel.c to
channel_internal_api.c (note: the AST_DATA stuff will have to be reworked to
use accessor functions when ast_channel is really opaque), and some re-working
of the way channel iterators/callbacks are handled so as to avoid creating fake
ast_channels on the stack to pass in matching data by directly accessing fields
(since "name" is a stringfield and the fake channel doesn't init the
stringfields, you can't use the ast_channel_name_set() function). I went with
ast_channel_name(chan) for a getter, and ast_channel_name_set(chan, name) for a
setter.
The majority of the grunt-work for this change was done by writing a semantic
patch using Coccinelle ( http://coccinelle.lip6.fr/ ).
Review: https://reviewboard.asterisk.org/r/1655/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@350223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
https://origsvn.digium.com/svn/asterisk/branches/10
................
r337120 | mjordan | 2011-09-20 17:49:36 -0500 (Tue, 20 Sep 2011) | 28 lines
Merged revisions 337118 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r337118 | mjordan | 2011-09-20 17:38:54 -0500 (Tue, 20 Sep 2011) | 21 lines
Fix for incorrect voicemail duration in external notifications
This patch fixes an issue where the voicemail duration was being reported
with a duration significantly less than the actual sound file duration.
Voicemails that contained mostly silence were reporting the duration of
only the sound in the file, as opposed to the duration of the file with
the silence. This patch fixes this by having two durations reported in
the __ast_play_and_record family of functions - the sound_duration and the
actual duration of the file. The sound_duration, which is optional, now
reports the duration of the sound in the file, while the actual full duration
of the file is reported in the duration parameter. This allows the voicemail
applications to use the sound_duration for minimum duration checking, while
reporting the full duration to external parties if the voicemail is kept.
(issue ASTERISK-2234)
(closes issue ASTERISK-16981)
Reported by: Mary Ciuciu, Byron Clark, Brad House, Karsten Wemheuer, KevinH
Tested by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/1443
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@337124 65c4cc65-6c06-0410-ace0-fbb531ad65f3
https://origsvn.digium.com/svn/asterisk/branches/10
................
r329528 | jrose | 2011-07-26 08:52:34 -0500 (Tue, 26 Jul 2011) | 24 lines
Merged revisions 329527 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8
........
r329527 | jrose | 2011-07-26 08:25:35 -0500 (Tue, 26 Jul 2011) | 17 lines
Fixes some voicemail forwarding behavior based around prepend mode.
Formerly, prepend forwarding would have the user record a message with no useful prompt
and an expectation for the user to push a button on the phone when finished recording.
If a length of silence was detected instead, the recording would be canceled and the user
would re-enter the voicemail forwarding menu. Subsequent time-outs in prepend recording
would also bug out in the sense that they would write over the original message and get
sent to the recipient regardless of whether they timed out or were accepted. This patch
fixes this issue and adds a prompt which will be played after a timeout informing the
user that they needed to press a button. Currently, the sound files that we have are
somewhat inadquate for this, so after the call we simply have Allison say "Please try
again. Then press pound." which actually relies on two separate sound files. Just one
would be more appropriate.
reporter: Vlad Povorozniuc
Review: https://reviewboard.asterisk.org/r/1327/
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@329530 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This patch is the foundation of an entire new way of looking at media in Asterisk.
The code present in this patch is everything required to complete phase1 of my
Media Architecture proposal. For more information about this project visit the link below.
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal
The primary function of this patch is to convert all the usages of format
bitfields in Asterisk to use the new format and format_cap APIs. Functionally
no change in behavior should be present in this patch. Thanks to twilson
and russell for all the time they spent reviewing these changes.
Review: https://reviewboard.asterisk.org/r/1083/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@306010 65c4cc65-6c06-0410-ace0-fbb531ad65f3
https://origsvn.digium.com/svn/asterisk/branches/1.8
................
r302634 | tilghman | 2011-01-19 14:24:57 -0600 (Wed, 19 Jan 2011) | 22 lines
Merged revisions 302599 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
........
r302599 | tilghman | 2011-01-19 14:13:24 -0600 (Wed, 19 Jan 2011) | 15 lines
Kill zombies.
When we ast_safe_fork() with a non-zero argument, we're expected to reap our
own zombies. On a zero argument, however, the zombies are only reaped when
there aren't any non-zero forked children alive. At other times, we
accumulate zombies. This code is forward ported from res_agi in 1.4, so that
forked children are always reaped, thus preventing an accumulation of zombie
processes.
(closes issue #18515)
Reported by: ernied
Patches:
20101221__issue18515.diff.txt uploaded by tilghman (license 14)
Tested by: ernied
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@302644 65c4cc65-6c06-0410-ace0-fbb531ad65f3
The purpose of this patch is to eliminate struct ast_callerid since it has
turned into a miscellaneous collection of various party information.
Eliminate struct ast_callerid and replace it with the following struct
organization:
struct ast_party_name {
char *str;
int char_set;
int presentation;
unsigned char valid;
};
struct ast_party_number {
char *str;
int plan;
int presentation;
unsigned char valid;
};
struct ast_party_subaddress {
char *str;
int type;
unsigned char odd_even_indicator;
unsigned char valid;
};
struct ast_party_id {
struct ast_party_name name;
struct ast_party_number number;
struct ast_party_subaddress subaddress;
char *tag;
};
struct ast_party_dialed {
struct {
char *str;
int plan;
} number;
struct ast_party_subaddress subaddress;
int transit_network_select;
};
struct ast_party_caller {
struct ast_party_id id;
char *ani;
int ani2;
};
The new organization adds some new information as well.
* The party name and number now have their own presentation value that can
be manipulated independently. ISDN supplies the presentation value for
the name and number at different times with the possibility that they
could be different.
* The party name and number now have a valid flag. Before this change the
name or number string could be empty if the presentation were restricted.
Most channel drivers assume that the name or number is then simply not
available instead of indicating that the name or number was restricted.
* The party name now has a character set value. SIP and Q.SIG have the
ability to indicate what character set a name string is using so it could
be presented properly.
* The dialed party now has a numbering plan value that could be useful to
have available.
The various channel drivers will need to be updated to support the new
core features as needed. They have simply been converted to supply
current functionality at this time.
The following items of note were either corrected or enhanced:
* The CONNECTEDLINE() and REDIRECTING() dialplan functions were
consolidated into func_callerid.c to share party id handling code.
* CALLERPRES() is now deprecated because the name and number have their
own presentation values.
* Fixed app_alarmreceiver.c write_metadata(). The workstring[] could
contain garbage. It also can only contain the caller id number so using
ast_callerid_parse() on it is silly. There was also a typo in the
CALLERNAME if test.
* Fixed app_rpt.c using ast_callerid_parse() on the channel's caller id
number string. ast_callerid_parse() alters the given buffer which in this
case is the channel's caller id number string. Then using
ast_shrink_phone_number() could alter it even more.
* Fixed caller ID name and number memory leak in chan_usbradio.c.
* Fixed uninitialized char arrays cid_num[] and cid_name[] in
sig_analog.c.
* Protected access to a caller channel with lock in chan_sip.c.
* Clarified intent of code in app_meetme.c sla_ring_station() and
dial_trunk(). Also made save all caller ID data instead of just the name
and number strings.
* Simplified cdr.c set_one_cid(). It hand coded the ast_callerid_merge()
function.
* Corrected some weirdness with app_privacy.c's use of caller
presentation.
Review: https://reviewboard.asterisk.org/r/702/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@276347 65c4cc65-6c06-0410-ace0-fbb531ad65f3