diff --git a/.gitignore b/.gitignore index 0281e107cf7..1a6deef24f1 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,5 @@ menuselect-tree *.gcda latex doxygen.log +out/ diff --git a/CHANGES b/CHANGES index 7d0b954a852..68617a44189 100644 --- a/CHANGES +++ b/CHANGES @@ -8,13 +8,647 @@ === ============================================================================== +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 15 to Asterisk 16 -------------------- +------------------------------------------------------------------------------ + +app_macro +------------------ + * The app_macro module is now deprecated and by default it is no longer + built. Users should migrate to app_stack (Gosub). A warning is logged + the first time any Macro is used. + +chan_sip +------------------ + * New function SIP_HEADERS() enumerates all headers in the incoming INVITE. + + * The variable GET_TRANSFERRER_DATA set in the peer channel causes matching + headers be retrieved from the REFER message and made accessible to the + dialplan in the hash TRANSFER_DATA. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 15.0.0 to Asterisk 15.1.0 ------------ +------------------------------------------------------------------------------ + +res_pjsip +------------------ + * The "remove_existing" option now allows a registration to succeed by + displacing any existing contacts that now exceed the "max_contacts" count. + Any removed contacts are the next to expire. The behaviour change is + beneficial when "rewrite_contact" is enabled and "max_contacts" is greater + than one. The removed contact is likely the old contact created by + "rewrite_contact" that the device is refreshing. + +AMI +------------------ + * Added a new CancelAtxfer action that cancels an attended transfer. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14 to Asterisk 15 -------------------- +------------------------------------------------------------------------------ + +app_queue +------------------ + * PAUSEALL/UNPAUSEALL now sets the pause reason in the queue_log if it has + been defined. + + * A new option, "announce-position-only-up," has been added that, when set to + yes, causes position announcements to only be played when the caller's + queue position has improved since the last time that we annouced their + position. This default is no. + +Build System +------------------ + * '--with-pjproject-bundled' is now the default when running ./configure + It can be disabled with '--without-pjproject-bundled'. + + * A '--with-download-cache' option is now available which is equivalent to + setting '--with-sounds-cache' and '--with-externals-cache' to the same + value. The download cache can also be set via the AST_DOWNLOAD_CACHE + environment variable. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.6.0 to Asterisk 14.7.0 ------------ +------------------------------------------------------------------------------ + +res_pjsip +------------------ + * The "external_media_address" on transports is now resolved using dnsmgr and + when dnsmgr refreshes are enabled will be automatically updated with the new + IP address of a given hostname. + + * A new endpoint parameter "incoming_mwi_mailbox" allows Asterisk to receive + unsolicited MWI NOTIFY requests and make them available to other modules via + the stasis message bus. + +res_musiconhold +------------------ + * By default, when res_musiconhold reloads or unloads, it sends a HUP signal + to custom applications (and all descendants), waits 100ms, then sends a + TERM signal, waits 100ms, then finally sends a KILL signal. An application + which is interacting with an external device and/or spawns children of its + own may not be able to exit cleanly in the default times, expecially if sent + a KILL signal, or if it's children are getting signals directly from + res_musiconhoild. To allow extra time, the 'kill_escalation_delay' + class option can be used to set the number of milliseconds res_musiconhold + waits before escalating kill signals, with the default being the current + 100ms. To control to whom the signals are sent, the "kill_method" + class option can be set to "process_group" (the default, existing behavior), + which sends signals to the application and its descendants directly, or + "process" which sends signals only to the application itself. + + * New dialplan function PJSIP_DTMF_MODE added to get or change the DTMF mode + of a channel on a per-call basis. + +res_xmpp +----------------- + * OAuth 2.0 authentication is now supported when contacting Google. Follow the + instructions in xmpp.conf.sample to retrieve and configure the necessary + tokens. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.5.0 to Asterisk 14.6.0 ------------ +------------------------------------------------------------------------------ + +app_voicemail +------------------ + * A new global option "imap_poll_logout" was added to specify whether need to + disconnect from the IMAP server after polling of mailboxes. + Default: no + +res_pjsip +------------------ + * A new endpoint option "refer_blind_progress" was added to turn off notifying + the progress details on Blind Transfer. If this option is not set then + the chan_pjsip will send NOTIFY "200 OK" immediately after "202 Accepted". + On default is enabled. + Some SIP phones like Mitel/Aastra or Snom keep the line busy until + receive "200 OK". + + * A new endpoint option "notify_early_inuse_ringing" was added to control + whether to notify dialog-info state 'early' or 'confirmed' on Ringing + when already INUSE. + + * The endpoint option 'dtmf_mode' has a new option 'auto_dtmf' added. This + mode works similar to 'auto' except uses DTMF INFO as fallback instead of + INBAND. + +res_agi +------------------ + * The EAGI() application will now look for a dialplan variable named + EAGI_AUDIO_FORMAT and use that format with the 'enhanced' audio pipe that + EAGI provides. If not specified, it will continue to use the default signed + linear (slin). + +chan_pjsip +------------------ + * When dialing an endpoint directly or using the PJSIP_DIAL_CONTACTS dialplan + function any contact which is considered unreachable due to qualify being + enabled will no longer be called. + + * The asymmetric_rtp_codec option now also controls whether chan_pjsip will + send media as-is without transcoding if the codec has been negotiated in the + SDP. If set to "no" then Asterisk will only ever send the preferred codec + from the SDP, unless the remote side sends a different codec and we will + switch to match. + +Build System +------------------ + * Added a new PJPROJECT_CONFIGURE_OPTS environment variable which can be used + to pass arbitrary options to the bundled pjproject configure. + + * Automatically set the bundled pjproject configure --host and --build + options to match those supplied for the asterisk configure. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.4.0 to Asterisk 14.5.0 ------------ +------------------------------------------------------------------------------ + +res_rtp_asterisk +------------------ + * Added the stun_blacklist option to rtp.conf. Some multihomed servers have + IP interfaces that cannot reach the STUN server specified by stunaddr. + Blacklist those interface subnets from trying to send a STUN packet to find + the external IP address. Attempting to send the STUN packet needlessly + delays processing incoming and outgoing SIP INVITEs because we will wait + for a response that can never come until we give up on the response. + Multiple subnets may be listed. + +Logging +------------------- + * Added logger_queue_limit to the configuration options. + All log messages go to a queue serviced by a single thread + which does all the IO. This setting controls how big that + queue can get (and therefore how much memory is allocated) + before new messages are discarded. + The default is 1000. + +res_pjsip_config_wizard +------------------ + * Two new parameters have been added to the pjsip config wizard. + Setting 'sends_line_with_registrations' to true will cause the wizard + to skip the creation of an identify object to match incoming requests + to the endpoint and instead add the line and endpoint parameters to + the outbound registration object. + Setting 'outbound_proxy' is a shortcut for adding individual + endpoint/outbound_proxy, aor/outbound_proxy and registration/outbound_proxy + parameters. + +res_hep_rtcp +------------------ + * If the 'call-id' value is specified for the uuid_type option and a + chan_sip channel is used the resulting HEP traffic will now contain the + SIP Call-ID instead of the Asterisk channel name. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.3.0 to Asterisk 14.4.0 ------------ +------------------------------------------------------------------------------ + +Build System +------------------ + * LOW_MEMORY no longer has an effect on Asterisk ABI. Symbols that were + previously suppressed by LOW_MEMORY are now replaced by stub functions. + Asterisk built with LOW_MEMORY can now successfully load binary modules + built without LOW_MEMORY and vice versa. + + * RADIUS backends for CEL and CDR can now also be built using the radcli + client library, in addition to the existing support for building them + using either freeradius or radiusclient-ng. + +Core +------------------ + * ASTERISK_REGISTER_FILE was no longer useful and has been removed. Sources + which use mtx_prof must now manually declare and initialize the variable. + +chan_sip +------------------ + * If an offer is received with optional SRTP (a media stream with RTP/AVP but + which contains a crypto line) chan_sip will now accept it and enable SRTP. + If you would like to do optional SRTP on outbound you will need to create + a dialplan that dials with it enabled initially and if it fails fall back to + without. + +res_pjsip +------------------ + * Added endpoint configuration parameter "preferred_codec_only". + This allow asterisk response to a SIP invite with the single most + preferred codec rather than advertising all joint codec capabilities. + This limits the other side's codec choice to exactly what we prefer. + +cdr_radius +------------------ + * To fix a memory leak the syslog channel is now empty if it has not been set + and used by a syslog channel in the logger. + +cel_radius +------------------ + * To fix a memory leak the syslog channel is now empty if it has not been set + and used by a syslog channel in the logger. + +RTP +------------------ + * New setting "rtp_pt_dynamic = 35" in asterisk.conf: + Normally the Dynamic RTP Payload Type numbers are 96-127, which allow just 32 + formats. To avoid the message "No Dynamic RTP mapping available", the range + was changed to 35-63,96-127. This is allowed by RFC 3551 section 3. However, + when you use more than 32 formats and calls are not accepted by a remote + implementation, please report this and go back to rtp_pt_dynamic = 96. + + * A new setting, "rtp_use_dynamic", has been added in asterisk.conf". When set + to "yes" RTP dynamic payload types are assigned dynamically per RTP instance. + When set to "no" RTP dynamic payload types are globally initialized to pre- + designated numbers and function similar to static payload types. + +app_originate +------------------ + * Added support to gosub predial routines on both original channel and on the + created channel using options parameter (like app_dial) B() and b(). This + allows for adding variables to newly created channel or, e.g. setting callerid. + +CLI Commands +------------------ + * 'dialplan show' output will now show [config_file:line_number] instead of + [registrar] when that information is available. Currently only extensions + registered by pbx_config when loading/reloading will use this format. + +app_queue +------------------ + * Add 'QueueUpdate' application which can be used to track outbound calls + using app_queue. + +pbx_spool +------------------ + * Asterisk will now set the AST_OUTGOING_ATTEMPT channel variable so that + attempt-specific behavior is possible. This is a 1-based number that + simply increases by 1 for each attempt. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.3.0 to Asterisk 14.4.0 ------------ +------------------------------------------------------------------------------ + +AMI +------------------ + * The 'PJSIPShowEndpoint' command's respone event of 'IdentifyDetail' now + contains a new optional parameter, 'MatchHeader', mapping to the new + configuration option 'match_header' for the corresponding 'identify' object. + It should be noted that since 'match_header' takes in a key: value pair, the + event parameter will contain a ':' as well. + +app_record +------------------ + * Added new 'u' option to Record() application which prevents Asterisk from + truncating silence from the end of recorded files. + +res_pjsip_outbound_registration +------------------ + * Outbound registrations are now refreshed when res_stun_monitor detects + a network change event has happened. + The 'pjsip send (un)register' CLI commands were updated to accept '*all' + as an argument to operate on all registrations. + The 'PJSIP(Un)Register' AMI commands were updated to also accept '*all'. + +app_voicemail +------------------ + * The 'Comedian Mail' prompts can now be overriden using the 'vm-login' and + 'vm-newuser' configuration options in voicemail.conf. + + * Added 'fromstring' field to the voicemail boxes. If set, it will override + the global 'fromstring' field on a per-mailbox basis. + +func_channel +------------------ + * Added CHANNEL(callid) to retrieve the call log tag associated with the + channel. e.g., [C-00000000] Dialplan now has access to the call log + search key associated with the channel so it can be saved in case there + is a problem with the call. + +res_pjsip +------------------ + * A new transport parameter 'symmetric_transport' has been added. + When a request from a dynamic contact comes in on a transport with this + option set to 'yes', the transport name will be saved and used for + subsequent outgoing requests like OPTIONS, NOTIFY and INVITE. It's + saved as a contact uri parameter named 'x-ast-txp' and will display with + the contact uri in CLI, AMI, and ARI output. On the outgoing request, + if a transport wasn't explicitly set on the endpoint AND the request URI + is not a hostname, the saved transport will be used and the 'x-ast-txp' + parameter stripped from the outgoing packet. To facilitate recreation of + subscriptions on asterisk restart, a new column 'contact_uri' needed to be + added to the ps_subcsription_persistence table. Since new columns were + added to both transport and subscription_persistence, an alembic upgrade + should be run to bring the database tables up to date. + + * A new option, allow_overlap, has been added to endpoints which allows + overlap dialing functionality to be enabled or disabled. The option defaults + to enabled. + +res_pjsip_transport_websocket +------------------ + * Removed non-secure websocket support. Firefox and Chrome have not allowed + non-secure websockets for quite some time so this shouldn't be an issue + for people. Attempting to use a non-secure websocket may or may not work + when Asterisk attempts to send SIP requests to do something like initiate + call hangup. + +res_pjsip_endpoint_identifier_ip +------------------ + * A new option has been added to the 'identify' configuration object, + 'match_header'. The 'match_header' attribute should contain a SIP + header: value pair that, When set, will cause inbound requests that contain + the matching SIP header/value pair to be associated with the corresponding + endpoint. This option is cumulative with the 'match' option, so that if + either option matches the request, the request is associated with the + endpoint. + + In a future release, this module will be renamed to something more + appropriate, as it now matches inbound requests on more than just IP + address. + +res_rtp_asterisk +----------------- + * The RTP layer of Asterisk now has support for RFC 5761: "Multiplexing RTP + Data and Control Packets on a Single Port." So far, the only channel driver + that supports this feature is chan_pjsip. You can set "rtcp_mux = yes" on + a PJSIP endpoint in pjsip.conf to enable the feature. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.2.0 to Asterisk 14.3.0 ------------ +------------------------------------------------------------------------------ + +res_pjproject +------------------ + * Added new CLI command "pjproject set log level". The new command allows + the maximum PJPROJECT log levels to be adjusted dynamically and + independently from the set debug logging level like many other similar + module debug logging commands. + + * Added new companion CLI command "pjproject show log level" to allow the + user to see the current maximum pjproject logging level. + + * Added new pjproject.conf startup section "log_level' option to set the + initial maximum PJPROJECT logging level. + +res_pjsip_outbound_registration +------------------ + * Statsd no longer logs redundant status PJSIP.registrations.state changes + for internal state transitions that don't change the reported public status + state. + +res_pjsip_registrar +------------------ + * The PJSIPShowRegistrationInboundContactStatuses AMI command has been added + to return ContactStatusDetail events as opposed to + PJSIPShowRegistrationsInbound which just a dumps every defined AOR. + +res_pjsip +------------------ + * Six existing contact fields have been added to the end of the + ContactStatusDetail AMI event: + ID, AuthenticateQualify, OutboundProxy, Path, QualifyFrequency and + QualifyTimeout. Existing fields have not been disturbed. + +res_pjsip_endpoint_identifier_ip +------------------ + * SRV lookups can now be done on provided hostnames to determine additional + source IP addresses for requests. This is configurable using the + "srv_lookups" option on the identify and defaults to "yes". + +ARI +------------------ + * The 'ari set debug' command has been enhanced to accept 'all' as an + application name. This allows dumping of all apps even if an app + hasn't registered yet. + + * 'ari set debug' now displays requests and responses as well as events. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.1.0 to Asterisk 14.2.0 ------------ +------------------------------------------------------------------------------ + +AMI +------------------ + * Events that reference a bridge may now contain two new optional fields: + - 'BridgeVideoSourceMode': the video source mode for the bridge. + Can be one of 'none', 'talker', or 'single'. + - 'BridgeVideoSource': the unique ID of the channel that is the video + source in this bridge, if one exists. + + * A new event, BridgeVideoSourceUpdate, has been added with a class + authorization of CALL. The event is raised when the video source changes + in a multi-party mixing bridge. + +ARI +------------------ + * The bridges resource now exposes two new operations: + - POST /bridges/{bridgeId}/videoSource/{channelId}: Set a video source in a + multi-party mixing bridge + - DELETE /bridges/{bridgeId}/videoSource: Remove the set video source, + reverting to talk detection for the video source + + * The bridge model in any returned response or event now contains the following + optional fields: + - video_mode: the video source mode for the bridge. Can be one of 'none', + 'talker', or 'single'. + - video_source_id: the unique ID of the channel that is the video source + in this bridge, if one exists. + + * A new event, BridgeVideoSourceChanged, has been added for bridges. + Applications subscribed to a bridge will receive this event when the source + of video changes in a mixing bridge. + + * The ARI major version has been bumped. There are not any known breaking changes + in ARI. The major version has been bumped because otherwise we can end up with + overlapping version numbers between different Asterisk versions. Now each major + version of Asterisk will bring with it a change in the major version of ARI. + The ARI version in Asterisk 14 is now 2.0.0. + +res_pjsip +------------------ + * Automatic dual stack support is now implemented. Depending on DNS resolution + and the transport used for sending a message the SIP signaling and SDP will + be updated with the correct IP address and protocol version. This means that + the rtp_ipv6 and t38_udptl_ipv6 options no longer have any effect. The + res_pjsip_multihomed module has also been moved into core res_pjsip to ensure + that messages are updated with the correct address information in all cases. + +chan_pjsip +------------------ + * The default behavior for RTP codecs has been changed. The sending codec will + now match the receiving codec. This can be turned off and behavior reverted + to asymmetric using the "asymmetric_rtp_codec" endpoint option. If this + option is set then the sending and received codec are allowed to differ. + +CLI Commands +------------------ + * Three new CLI commands have been added for ARI: + - ari show apps: + Displays a listing of all registered ARI applications. + - ari show app : + Display detailed information about a registered ARI application. + - ari set debug : + Enable/disable debugging of an ARI application. When debugged, verbose + information will be sent to the Asterisk CLI. + + +Queue +------------------ + * A new dialplan variable, ABANDONED, is set when the call is not answered + by an agent. + +res_ari +------------------ + * The configuration file ari.conf now supports a channelvars option, which + specifies a list of channel variables to include in each channel-oriented + ARI event. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.0.0 to Asterisk 14.1.0 ------------ +------------------------------------------------------------------------------ + +Build System +------------------ + * The res_digium_phone, codec_g729a, codec_silk, codec_siren7 and + codec_siren14 binary modules hosted at downloads.digium.com can now be + automatically downloaded and installed during the Asterisk install + process. If selected in menuselect, when 'make install' is run, the + script will check the downloads site for a new version and download + and install it if needed. The '--with-externals-cache' option to + ./configure can be used to specify a location to cache the latest + tarballs so they don't have to be re-downloaded for every install. + +app_voicemail +------------------ + * Added "tps_queue_high" and "tps_queue_low" options. + The options can modify the taskprocessor alert levels for this module. + Additional information can be found in the sample configuration file at + config/samples/voicemail.conf.sample. + +res_pjsip_mwi +------------------ + * Added "mwi_tps_queue_high" and "mwi_tps_queue_low" global configuration + options to tune taskprocessor alert levels. + + * Added "mwi_disable_initial_unsolicited" global configuration option + to disable sending unsolicited MWI to all endpoints on startup. + Additional information can be found in the sample configuration file at + config/samples/pjsip.conf.sample. + +chan_pjsip +------------------ + * A new dialplan function, PJSIP_SEND_SESSION_REFRESH, has been added. When + invoked, a re-INVITE or UPDATE request will be sent immediately to the + endpoint underlying the channel. When used in combination with the existing + dialplan function PJSIP_MEDIA_OFFER, this allows the formats on a PJSIP + channel to be re-negotiated and updated after session set up. + +res_pjsip +------------------ + * A new endpoint configuration parameter 'contact_user' has been added which + when set will override the default user set on Contact headers in outgoing + requests. + + * If you are using a sorcery realtime backend to store global res_pjsip + options (ps_globals table) then you now have to do a res_pjsip reload for + changes to these options to take effect. If you are using pjsip.conf to + configure these options then you already had to do a reload after making + changes. + + * Added "ignore_uri_user_options" global configuration option for + compatibility with an ITSP that sends URI user field options. When enabled + the user field is truncated at the first semicolon. + Example: + URI: "sip:1235557890;phone-context=national@x.x.x.x;user=phone" + The user field is "1235557890;phone-context=national" + Which is truncated to this: "1235557890" + + Note: The caller-id and redirecting number strings obtained from incoming + SIP URI user fields are now always truncated at the first semicolon. + +res_rtp_asterisk +------------------ + * An option, ice_blacklist, has been added which allows certain subnets to be + excluded from local ICE candidates. + +app_confbridge +------------------ + * Some sounds played into the bridge are played asynchronously. This, for + instance, allows a channel to immediately exit the ConfBridge without having + to wait for a leave announcement to play. + +app_dial +------------------ + * Added the "Q" option which sets the Q.850/Q.931 cause on unanswered channels + when another channel answers the call. The default of ANSWERED_ELSEWHERE + is unchanged. + +res_ari +------------------ + * ARI events will all now include a new field in the root of the JSON message, + 'asterisk_id'. This will be the unique ID for the Asterisk system + transmitting the event. The value can be overridden using the 'entityid' + setting in asterisk.conf. + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13 to Asterisk 14 -------------------- ------------------------------------------------------------------------------ +AMI +----------------- + * A new event, "DialState" has been added. This is similar to "DialBegin" and + "DialEnd" in that it tracks the state of a dialed call. The difference is that + this indicates some intermediate state change in the dial attempt, such as + "RINGING", "PROGRESS", or "PROCEEDING". + +ARI +----------------- + * A new ARI method has been added to the channels resource. "create" allows for + you to create a new channel and place that channel into a Stasis application. + This is similar to origination except that the specified channel is not + dialed. This allows for an application writer to create a channel, perform + manipulations on it, and then delay dialing the channel until later. + + * To complement the "create" method, a "dial" method has been added to the + channels resource in order to place a call to a created channel. + + * All operations that initiate playback of media on a resource now support + a list of media URIs. The list of URIs are played in the order they are + presented to the resource. A new event, "PlaybackContinuing", is raised when + a media URI finishes but before the next media URI starts. When a list is + played, the "Playback" model will contain the optional attribute + "next_media_uri", which specifies the next media URI in the list to be played + back to the resource. The "PlaybackFinished" event is raised when all media + URIs are done. + + * Stored recordings now allow for the media associated with a stored recording + to be retrieved. The new route, GET /recordings/stored/{name}/file, will + transmit the raw media file to the requester as binary. + + + * "Dial" events have been modified to not only be sent when dialing begins and ends. + They now are also sent for intermediate states, such as "RINGING", "PROGRESS", and + "PROCEEDING". + Applications ------------------ +BridgeAdd +------------------ + * A new application in Asterisk, this will join the calling channel + to an existing bridge containing the named channel prefix. + +ChanSpy +------------------ + * Added the 'l' option, which forces ChanSpy's audiohook to use a long queue + to store the audio frames. This option is useful if audio loss is + experienced when using ChanSpy, but may introduce some delay in the audio + feed on the listening channel. + +Codecs +------------------ + * Added format attribute negotiation for the iLBC audio codec. Format attribute + negotiation is provided by the res_format_attr_ilbc module. iLBC 20 is the + default now. Falls back to iLBC 30, when the remote party requests this. + ConfBridge ------------------ * Added the ability to pass options to MixMonitor when recording is used with @@ -26,25 +660,42 @@ ConfBridge - record_command: a command to execute when recording is finished Note that these options may also be with the CONFBRIDGE function. -SMS +ControlPlayback ------------------ - * Added the 'n' option, which prevents the SMS from being written to the log - file. This is needed for those countries with privacy laws that require - providers to not log SMS content. + * Remote files can now be retrieved and played back. See the Playback + dialplan application for more details. - -CDRs ------------------- -cdr_odbc +FollowMe ------------------ - * Added a new configuration option, "newcdrcolumns", which enables use of the - post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'. + * It is now possible to disable the prompt from a callee by setting + 'enable_callee_prompt = no' in followme.conf. +Playback ------------------ -cdr_csv + * Remote files can now be retrieved and played back via the Playback and other + media playback dialplan applications. This is done by directly providing + the URL to play to the dialplan application: + same => n,Playback(http://1.1.1.1/howler-monkeys-fl.wav) + Note that unlike 'normal' media files, the entire URI to the file must be + provided, including the file extension. Currently, on HTTP and HTTPS URI + schemes are supported. + +Queue +------------------- + * Added field ReasonPause on QueueMemberStatus if set when paused, the reason + the queue member was paused. + + * Added field LastPause on QueueMemberStatus for time when started the last + pause for a queue member. + + * Show the time when started the last pause for queue member on CLI for command + 'queue show'. + +SMS ------------------ - * Added a new configuration option, "newcdrcolumns", which enables use of the - post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'. + * Added the 'n' option, which prevents the SMS from being written to the log + file. This is needed for those countries with privacy laws that require + providers to not log SMS content. Channel Drivers @@ -54,6 +705,7 @@ chan_dahdi ------------------ * The CALLERID(ani2) value for incoming calls is now populated in featdmf signaling mode. The information was previously discarded. + * Added the force_restart_unavailable_chans compatibility option. When enabled it causes Asterisk to restart the ISDN B channel if an outgoing call receives cause 44 (Requested channel not available). @@ -63,34 +715,83 @@ chan_iax2 * The iax.conf forcejitterbuffer option has been removed. It is now always forced if you set iax.conf jitterbuffer=yes. If you put a jitter buffer on a channel it will be on the channel. + * A new configuration parameters, 'calltokenexpiration', has been added that controls the duration before a call token expires. Default duration is 10 seconds. Setting this to a higher value may help in lagged networks or those experiencing high packet loss. + * Plaintext auth mode is deprecated and removed from possible default modes. + +chan_rtp (was chan_multicast_rtp) +------------------ + * Added unicast RTP support and renamed chan_multicast_rtp to chan_rtp. + + * The format for dialing a unicast RTP channel is: + UnicastRTP/[/[]] + Where is something like '127.0.0.1:5060'. + Where are in standard Asterisk flag options format: + c() - Specify which codec/format to use such as 'ulaw'. + e() - Specify which RTP engine to use such as 'asterisk'. + + * New options were added for a multicast RTP channel. The format for + dialing a multicast RTP channel is: + MulticastRTP//[/[][/[]]] + Where can be either 'basic' or 'linksys'. + Where is something like '224.0.0.3:5060'. + Where is something like '127.0.0.1:5060'. + Where are in standard Asterisk flag options format: + c() - Specify which codec/format to use such as 'ulaw'. + i(
) - Specify the interface address from which multicast RTP + is sent. + l() - Set whether packets are looped back to the sender. The + enable value can be 0 to set looping to off and non-zero to set + looping on. + t() - Set the time-to-live (TTL) value for multicast packets. + chan_sip ------------------ * New 'rtpbindaddr' global setting. This allows a user to define which ipaddress to bind the rtpengine to. For example, chan_sip might bind to eth0 (10.0.0.2) but rtpengine to eth1 (192.168.1.10). + * DTLS related configuration options can now be set at a general level. Enabling DTLS support, though, requires enabling it at the user or peer level. + * Added the possibility to set the From: header through the the SIP dial + string (populating the fromuser/fromdomain fields), complementing the + [!dnid] option for the To: header that has existed since 1.6.0 (1d6b192). + NOTE: This is again separated by an exclamation mark, so the To: header may + not contain one of those. + + * Session-Timers (RFC 4028) work for TCP (and TLS) transports as well now. + Previously Asterisk dropped calls only with UDP transports. However with + longer international calls via TCP, the SIP channel might break, because + all hops on the Internet route must stay online (have not a single power + outage, for example). Therefore with Session-Timers enabled (which are + enabled at default), you might see additional dropped calls. Consequently + please, consider to go for session-timers=refuse in your sip.conf. + chan_pjsip ------------------ * New 'user_eq_phone' endpoint setting. This adds a 'user=phone' parameter - to the request URI and From URI if the user is determined to be a phone number. - * New 'moh_passthrough' endpoint setting. This will pass hold and unhold requests - through using SIP re-invites with sendonly and sendrecv accordingly. + to the request URI and From URI if the user is determined to be a phone + number. + + * New 'moh_passthrough' endpoint setting. This will pass hold and unhold + requests through using SIP re-invites with sendonly and sendrecv accordingly. + * Added the pjsip.conf system type disable_tcp_switch option. The option allows the user to disable switching from UDP to TCP transports described by RFC 3261 section 18.1.1. - * New 'line' and 'endpoint' options added on outbound registrations. This allows some - identifying information to be added to the Contact of the outbound registration. - If this information is present on messages received from the remote server - the message will automatically be associated with the configured endpoint on the - outbound registration. + + * New 'line' and 'endpoint' options added on outbound registrations. This + allows some identifying information to be added to the Contact of the + outbound registration. If this information is present on messages received + from the remote server the message will automatically be associated with the + configured endpoint on the outbound registration. + Core ------------------ @@ -122,24 +823,67 @@ Core of '[json]' can be set, e.g., full => [json]debug,verbose,notice,warning,error + * The core now supports a 'media cache', which stores temporary media files + retrieved from external sources. CLI commands have been added to manipulate + and display the cached files, including: + - 'media cache show ' - show all cached media files, or details about + one particular cached media file + - 'media cache refresh ' - force a refresh of a particular media file + in the cache + - 'media cache delete ' - remove an item from the cache + - 'media cache create ' - retrieve a URI and store it in the cache + + * The ability for device state hints to be automatically created as a result of + device state changes now exists in the PBX. This functionality is referred to + as "autohints" and is configurable in extensions.conf by placing "autohints=yes" + in the context. If enabled a device state hint will be automatically created + with the name of the device. + +* If Asterisk is built with systemd support, and run under systemd, it will + notify systemd of its state using sd_notify. Use 'Type=notify' in + asterisk.service. + Functions ------------------ + * The func_odbc global option "single_db_connection" default value has been + changed to 'no'. + + +Formats +------------------ + * New module format_ogg_speex added which supports Speex codec inside + Ogg containers (filename extension .spx). + CHANNEL ------------------ * Added CHANNEL(onhold) item that returns 1 (onhold) and 0 (not-onhold) for the hold status of a channel. +CURL +------------------ + * The CURL function now supports a write option, which will save the retrieved + file to a location on disk. As an example: + same => n,Set(CURL(https://1.1.1.1/foo.wav)=/tmp/foo.wav) + will save 'foo.wav' to /tmp. + DTMF Features ------------------ * The transferdialattempts default value has been changed from 1 to 3. The - transferinvalidsound has been changed from "pbx-invalid" to "privacy-incorrect". - These were changed to make DTMF transfers be more user-friendly by default. + transferinvalidsound has been changed from "pbx-invalid" to + "privacy-incorrect". These were changed to make DTMF transfers be more + user-friendly by default. Resources ------------------ +res_http_media_cache +------------------ + * A backend for the core media cache, this module retrieves media files from + a remote HTTP(S) server and stores them in the core media cache for later + playback. + res_musiconhold ------------------ * Added sort=randstart to the sort options. It sorts the files by name and @@ -162,6 +906,12 @@ res_pjsip will be used instead. The new SIP resolver provides NAPTR support, improved SRV support, and AAAA record support. +res_pjsip_info_empty +-------------------- + * A new module that can respond to empty Content-Type INFO packets during call. + Some SBCs will terminate a call if their empty INFO packets are not responded + to within a predefined time. + res_pjsip_outbound_registration ------------------------------- * A new 'fatal_retry_interval' option has been added to outbound registration. @@ -169,6 +919,12 @@ res_pjsip_outbound_registration outbound registration, registration is retried at the given interval up to 'max_retries'. +res_pjsip_outbound_publish +------------------ + * Added a new multi_user option that when set to 'yes' allows a given configuration + to be used for multiple users. + + CEL Backends ------------------ @@ -181,6 +937,7 @@ cel_pgsql configurable for cel_pgsql via the 'schema' in configuration file cel_pgsql.conf. + CDR Backends ------------------ @@ -191,15 +948,341 @@ cdr_adaptive_odbc names. This setting is configurable for cdr_adaptive_odbc via the quoted_identifiers in configuration file cdr_adaptive_odbc.conf. -Queue -------------------- - * Added field ReasonPause on QueueMemberStatus if set when paused, the reason - the queue member was paused. +cdr_odbc +------------------ + * Added a new configuration option, "newcdrcolumns", which enables use of the + post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'. + +cdr_csv +------------------ + * Added a new configuration option, "newcdrcolumns", which enables use of the + post-1.8 CDR columns 'peeraccount', 'linkedid', and 'sequence'. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 13.10.0 to Asterisk 13.11.0 ---------- +------------------------------------------------------------------------------ + +chan_dahdi +------------------ + * Added "faxdetect_timeout" option. + The option determines how many seconds into a call before faxdetect + is disabled for the call. Setting the value to zero disables the timeout. + +res_pjsip +------------------ + * Added "fax_detect_timeout" to endpoint. + The option determines how many seconds into a call before fax_detect + is disabled for the call. Setting the value to zero disables the timeout. + + * Added "subscribe_context" to endpoint. + If specified, incoming SUBSCRIBE requests will be searched for the matching + extension in the indicated context. If no "subscribe_context" is specified, + then the "context" setting is used. + +res_rtp_asterisk +------------------ + * The DTLS part in Asterisk now supports Perfect Forward Secrecy (PFS). + Enabling PFS is attempted by default, and is dependent on the configuration + of the module using TLS. + - Ephemeral ECDH (ECDHE) is enabled by default. To disable it, do not + specify a ECDHE cipher suite in sip.conf, for example: + dtlscipher=AES128-SHA + - Ephemeral DH (DHE) is disabled by default. To enable it, add DH parameters + into the private key file, e.g., sip.conf dtlsprivatekey. For example: + openssl dhparam -out ./dh.pem 2048 + - Because clients expect the server to prefer PFS, and because OpenSSL sorts + its cipher suites by bit strength, see "openssl ciphers -v DEFAULT". + Consider re-ordering your cipher suites in the respective configuration + file. For example: + dtlscipher=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 + which forces PFS and requires at least DTLS 1.2. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 13.9.0 to Asterisk 13.10.0 ----------- +------------------------------------------------------------------------------ + +Core +------------------ + * A channel variable FORWARDERNAME is now set which indicates which channel + was responsible for a forwarding requests received on dial attempt. + +func_odbc +------------------ + * Added new global option "single_db_connection". + Enabling this option func_odbc will use a single database connection per DSN. + This option is enabled by default. + +res_fax +------------------ + * Added FAXMODE variable to let dialplan know what fax transport was used. + FAXMODE variable is set to either "audio" or "T38". + +res_pjsip +------------------ + * Added "via_addr", "via_port", "call_id" to contacts. + As res_pjsip_nat rewrites contact's address, only the last Via header + can contain the source address of registered endpoint. + Also Call-Id header may contain the source address of registered endpoint. + Added new fields ViaAddress,CallID to AMI event ContactStatus + + * Endpoint IP Access Controls + Added new configuration Endpoint options: + "acl" - list of IP ACL section names in acl.conf + "deny" - List of IP addresses to deny access from + "permit" - List of IP addresses to permit access from + "contact_acl" - List of Contact ACL section names in acl.conf + "contact_deny" - List of Contact header addresses to deny + "contact_permit" - List of Contact header addresses to permit + + * Added "reg_server" to contacts. + If the Asterisk system name is set in asterisk.conf, it will be stored + into the "reg_server" field in the ps_contacts table to facilitate + multi-server setups. + + * When starting Asterisk, received traffic will now be ignored until Asterisk + has loaded all modules and is fully booted. + +res_hep +------------------ + * Added a new option, 'uuid_type', that sets the preferred source of the Homer + correlation UUID. The valid options are: + - call-id: Use the PJSIP SIP Call-ID header value + - channel: Use the Asterisk channel name + The default value is 'call-id'. In the event that a HEP module cannot find a + valid value using the specified 'uuid_type', the module may fallback to a + more readily available source for the correlation UUID. + +res_odbc +------------------ + * A new option has been added, 'max_connections', which sets the maximum number + of concurrent connections to the database. This option defaults to 1 which + returns the behavior to that of Asterisk 13.7 and prior. + +app_confbridge +------------------ + * Added a bridge profile option called regcontext that allows you to + dynamically register the conference bridge name as an extension into + the specified context. This allows tracking down conferences on multi- + server installations via alternate means (DUNDI for example). By default + this feature is not used. + +Codecs +------------------ + * Added the associated format name to 'core show codecs'. + +res_ari_channels +------------------ + * Added 'formats' to channel create/originate to allow setting the allowed + formats for a channel when no originator channel is available. Especially + useful for Local channel creation where no other format information is + available. 'core show codecs' can now be used to look up suitable format + names. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 13.8.0 to Asterisk 13.9.0 ------------ +------------------------------------------------------------------------------ + +res_parking: + - The dynamic parking lot creation channel variables PARKINGDYNAMIC, + PARKINGDYNCONTEXT, PARKINGDYNEXTEN, and PARKINGDYNPOS are now looked + for in the parker's channel instead of the parked channel. This is only + of significance if the parker uses blind transfer or the DTMF one-step + parking feature. You need to use the double underscore '__' inheritance + for these variables. The indefinite inheritance is also recommended + for the PARKINGEXTEN variable. + +res_pjsip +------------------ + * Added new global option (disable_multi_domain) to pjsip. + Disabling Multi Domain can improve realtime performace by reducing + number of database requsts. + +chan_pjsip +------------------ + * Added 'pjsip show channelstats' CLI command. + +res_pjsip_outbound_publish +------------------ + * Added support for setting the transport used on outbound publish + using the transport configuration option. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 13.7.0 to Asterisk 13.8.0 ------------ +------------------------------------------------------------------------------ + +res_pjsip_caller_id +------------------ + * Per RFC3325, the 'From' header is now anonymized on outgoing calls when + caller id presentation is prohibited. + +res_pjsip_config_wizard +------------------ + * A new command (pjsip export config_wizard primitives) has been added that + will export all the pjsip objects it created to the console or a file + suitable for reuse in a pjsip.conf file. + +Build System +------------------ + * To help insure that Asterisk is compiled and run with the same known + version of pjproject, a new option (--with-pjproject-bundled) has been + added to ./configure. When specified, the version of pjproject specified + in third-party/versions.mak will be downloaded and configured. When you + make Asterisk, the build process will also automatically build pjproject + and Asterisk will be statically linked to it. Once a particular version + of pjproject is configured and built, it won't be configured or built + again unless you run a 'make distclean'. + + To facilitate testing, when 'make install' is run, the pjsua and pjsystest + utilities and the pjproject python bindings will be installed in + ASTDATADIR/third-party/pjproject. + + The default behavior remains building with the shared pjproject + installation, if any. + +app_confbridge +------------------ + * Added CONFBRIDGE_INFO(muted,) for querying the muted conference state. + + * Added Muted header to AMI ConfbridgeListRooms action response list events + to indicate the muted conference state. + + * Added Muted column to CLI "confbridge list" output to indicate the muted + conference state and made the locked column a yes/no value instead of a + locked/unlocked value. + +REDIRECTING(reason) +------------------ + * The REDIRECTING(reason) value is now treated consistently between + chan_sip and chan_pjsip. + + Both channel drivers match incoming reason values with values documented + by REDIRECTING(reason) and values documented by RFC5806 regardless of + whether they are quoted or not. RFC5806 values are mapped to the + equivalent REDIRECTING(reason) documented value and is set in + REDIRECTING(reason). e.g., an incoming RFC5806 'unconditional' value or a + quoted string version ('"unconditional"') is converted to + REDIRECTING(reason)'s 'cfu' value. The user's dialplan only needs to deal + with 'cfu' instead of any of the aliases. + + The incoming 480 response reason text supported by chan_sip checks for + known reason values and if not matched then puts quotes around the reason + string and assigns that to REDIRECTING(reason). + + Both channel drivers send outgoing known REDIRECTING(reason) values as the + unquoted RFC5806 equivalent. User custom values are either sent as is or + with added quotes if SIP doesn't allow a character within the value as + part of a RFC3261 Section 25.1 token. Note that there are still + limitations on what characters can be put in a custom user value. e.g., + embedding quotes in the middle of the reason string is just going to cause + you grief. + + * Setting a REDIRECTING(reason) value now recognizes RFC5806 aliases. + e.g., Setting REDIRECTING(reason) to 'unconditional' is converted to the + 'cfu' value. + +res_pjproject +------------------ + * This module is the successor of res_pjsip_log_forwarder. As well as + handling the log forwarding (which now displays as 'pjproject:0' instead + of 'pjsip:0'), it also adds a 'pjproject show buildopts' command to the CLI. + This displays the compiled-in options of the pjproject installation + Asterisk is currently running against. + + * Another feature of this module is the ability to map pjproject log levels + to Asterisk log levels, or to suppress the pjproject log messages + altogether. Many of the messages emitted by pjproject itself are the result + of errors which Asterisk will ultimately handle so the messages can be + misleading or just noise. A new config file (pjproject.conf) has been added + to configure the mapping and a new CLI command (pjproject show log mappings) + has been added to display the mappings currently in use. + +res_pjsip +------------------ + * Transports are now reloadable. In testing, no in-progress calls were + disrupted if the ip address or port weren't changed, but the possibility + still exists. To make sure there are no unintentional drops, a new option + 'allow_reload', which defaults to 'no' has been added to transport. If + left at the default, changes to the particular transport will be ignored. + If set to 'yes', changes (if any) will be applied. + + * Added new global option (regcontext) to pjsip. When set, Asterisk will + dynamically create and destroy a NoOp priority 1 extension + for a given endpoint who registers or unregisters with us. + + * Endpoints and aors can now be identified by the username and realm in an + incoming Authorization header. To use this feature, add "auth_username" + to your endpoint's "identify_by" list. You can combine "auth_username" + and the original "username" to test both the From/To and Authorization + headers. For endpoints, the order is controlled by the global + "endpoint_identifier_order" setting. For matching aors to an endpoint + for inbound registration, the order is controlled by this option. + + * In conjunction with the "auth_username" change, 3 new options have been + added to the global configuration object that control how many unidentified + requests over a certain period from the same IP address can be received + before a security altert is generated. A new CLI command + "pjsip show unidentified_requests" will list the current candidates. + +res_pjsip_history +------------------ + * A new module, res_pjsip_history, has been added that provides SIP history + viewing/filtering from the CLI. The module is intended to be used on systems + with busy SIP traffic, where existing forms of viewing SIP messages - such + as the res_pjsip_logger - may be inadequate. The module provides two new + CLI commands: + - 'pjsip set history {on|off|clear}' - this enables/disables SIP history + capturing, as well as clears an existing history capture. Note that SIP + packets captured are stored in memory until cleared. As a result, the + history capture should only be used for debugging/viewing purposes, and + should *NOT* be left permanently enabled on a system. + - 'pjsip show history' - displays the captured SIP history. When invoked + with no options, the entire captured history is displayed. Two options + are available: + -- 'entry ' - display a detailed view of a single SIP message in + the history + -- 'where ...' - filter the history based on some expression. For more + information on filtering, view the current CLI help for the + 'pjsip show history' command. + +Voicemail +------------------ + * app_voicemail and res_mwi_external can now be built together. The default + remains to build app_voicemail and not res_mwi_external but if they are + both built, the load order will cause res_mwi_external to load first and + app_voicemail will be skipped. Use 'preload=app_voicemail.so' in + modules.conf to force app_voicemail to be the voicemail provider. + +res_pjsip_sdp_rtp +------------------ + * A new option (bind_rtp_to_media_address) has been added to endpoint which + will cause res_pjsip_sdp_rtp to actually bind the RTP instance to the + media_address as well as using it in the SDP. If set, RTP packets will now + originate from the media address instead of the operating system's "primary" + ip address. + +res_rtp_asterisk +------------------ + * A new configuration section - ice_host_candidates - has been added to + rtp.conf, allowing automatically discovered ICE host candidates to be + overriden. This allows an Asterisk server behind a 1:1 NAT to send its + external IP as a host candidate rather than relying on STUN to discover it. ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.6.0 to Asterisk 13.7.0 ------------ ------------------------------------------------------------------------------ +Codecs +------------------ + * Added format attribute negotiation for the VP8 video codec. Format attribute + negotiation is provided by the res_format_attr_vp8 module. + +ConfBridge +------------------ + * A new "timeout" user profile option has been added. This configures the number + of seconds that a participant may stay in the ConfBridge after joining. When + the time expires, the user is ejected from the conference and CONFBRIDGE_RESULT + is set to "TIMEOUT" on the channel. + chan_sip ------------------ * The websockets_enabled option has been added to the general section of @@ -215,12 +1298,60 @@ Dialplan Functions the 'hold' raised by a channel to be intercepted and converted into an event instead. +res_pjsip_outbound_registration +------------------------------- + * If res_statsd is loaded and a StatsD server is configured, basic statistics + regarding the state of outbound registrations will now be emitted. This + includes: + - A GAUGE statistic for the overall number of outbound registrations, i.e.: + PJSIP.registrations.count + - A GAUGE statistic for the overall number of outbound registrations in a + particular state, e.g.: + PJSIP.registrations.state.Registered res_pjsip ------------------ * The ability to use "like" has been added to the pjsip list and show CLI commands. For instance: CLI> pjsip list endpoints like abc + * If res_statsd is loaded and a StatsD server is configured, basic statistics + regarding the state of PJSIP contacts will now be emitted. This includes: + - A GAUGE statistic for the overall number of contacts in a particular + state, e.g.: + PJSIP.contacts.states.Reachable + - A TIMER statistic for the RTT time for each qualified contact, e.g.: + PJSIP.contacts.alice@@127.0.0.1:5061.rtt + +res_sorcery_memory_cache +------------------------ + * A new caching strategy, full_backend_cache, has been added which caches + all stored objects in the backend. When enabled all objects will be + expired or go stale according to the configuration. As well when enabled + all retrieval operations will be performed against the cache instead of + the backend. + +func_callerid +------------------- + * CALLERID(pres) is now documented as a valid alternative to setting both + CALLERID(name-pres) and CALLERID(num-pres) at once. Some channel drivers, + like chan_sip, don't make a distinction between the two: they take the + least public value from name-pres and num-pres. By using CALLERID(pres) + for reading and writing, you touch the same combined value in the dialplan. + The same applies to CONNECTEDLINE(pres), REDIRECTING(orig-pres), + REDIRECTING(to-pres) and REDIRECTING(from-pres). + +res_endpoint_stats +------------------- + * A new module that emits StatsD statistics regarding Asterisk endpoints. + This includes a total count of the number of endpoints, the count of the + number of endpoints in the technology agnostic state of the endpoint - + online or offline - as well as the number of channels associated with each + endpoint. These are recorded as three different GAUGE statistics: + - endpoints.count + - endpoints.state.{unknown|offline|online} + - endpoints.{tech}.{resource}.channels + + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 13.5.0 to Asterisk 13.6.0 ------------ ------------------------------------------------------------------------------ @@ -463,7 +1594,7 @@ res_pjsip_endpoint_identifer_ip ------------------ * New CLI commands have been added: "pjsip show identif(y|ies)", which lists all configured PJSIP identify objects - + ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 12 to Asterisk 13 -------------------- ------------------------------------------------------------------------------ @@ -568,6 +1699,8 @@ Say language. The 'language' parameter in say.conf now recognizes a setting of 'ja', which will enable Japanese language specific mechanisms for playing back numbers, dates, and other items. + * Counting, enumeration and dates now supports Icelandic grammar with the + 'language' parameter set to 'is'. SayCountPL ------------------ @@ -4721,6 +5854,7 @@ Voicemail Changes the message as urgent after he has recorded a voicemail by following the voice instructions. When listening to voicemails using VoiceMailMain urgent messages will be presented before other messages + * Added "is" language support Queue changes ------------- diff --git a/Makefile b/Makefile index 4b1c57b8bc5..85a1152eac7 100644 --- a/Makefile +++ b/Makefile @@ -99,8 +99,15 @@ export WGET_EXTRA_ARGS export LDCONFIG export LDCONFIG_FLAGS export PYTHON - --include makeopts +export TAR +export PATCH +export SED +export NM + +# makeopts is required unless the goal is clean or distclean +ifeq ($(findstring clean,$(MAKECMDGOALS)),) +include makeopts +endif # start the primary CFLAGS and LDFLAGS with any that were provided # to the configure script @@ -117,6 +124,9 @@ _ASTLDFLAGS+=$(LDOPTS) # libxml2 cflags _ASTCFLAGS+=$(LIBXML2_INCLUDE) +# BIND_8_COMPAT +_ASTCFLAGS+=$(BIND8_CFLAGS) + #Uncomment this to see all build commands instead of 'quiet' output #NOISY_BUILD=yes @@ -175,11 +185,6 @@ OTHER_SUBDIR_CFLAGS="-I$(ASTTOPDIR)/include" # Create OPTIONS variable, but probably we can assign directly to ASTCFLAGS OPTIONS= -ifeq ($(OSARCH),linux-gnu) - # flag to tell 'ldconfig' to only process specified directories - LDCONFIG_FLAGS=-n -endif - ifeq ($(findstring -save-temps,$(_ASTCFLAGS) $(ASTCFLAGS)),) ifeq ($(findstring -pipe,$(_ASTCFLAGS) $(ASTCFLAGS)),) _ASTCFLAGS+=-pipe @@ -215,8 +220,6 @@ ifeq ($(OSARCH),FreeBSD) # -V is understood by BSD Make, not by GNU make. BSDVERSION=$(shell make -V OSVERSION -f /usr/share/mk/bsd.port.subdir.mk) _ASTCFLAGS+=$(shell if test $(BSDVERSION) -lt 500016 ; then echo "-D_THREAD_SAFE"; fi) - # flag to tell 'ldconfig' to only process specified directories - LDCONFIG_FLAGS=-m endif ifeq ($(OSARCH),NetBSD) @@ -246,16 +249,13 @@ endif _ASTCFLAGS+=$(OPTIONS) -MOD_SUBDIRS:=channels pbx apps codecs formats cdr cel bridges funcs tests main res addons $(LOCAL_MOD_SUBDIRS) +MOD_SUBDIRS:=third-party channels pbx apps codecs formats cdr cel bridges funcs tests main res addons $(LOCAL_MOD_SUBDIRS) OTHER_SUBDIRS:=utils agi contrib SUBDIRS:=$(OTHER_SUBDIRS) $(MOD_SUBDIRS) SUBDIRS_INSTALL:=$(SUBDIRS:%=%-install) SUBDIRS_CLEAN:=$(SUBDIRS:%=%-clean) SUBDIRS_DIST_CLEAN:=$(SUBDIRS:%=%-dist-clean) SUBDIRS_UNINSTALL:=$(SUBDIRS:%=%-uninstall) -MOD_SUBDIRS_EMBED_LDSCRIPT:=$(MOD_SUBDIRS:%=%-embed-ldscript) -MOD_SUBDIRS_EMBED_LDFLAGS:=$(MOD_SUBDIRS:%=%-embed-ldflags) -MOD_SUBDIRS_EMBED_LIBS:=$(MOD_SUBDIRS:%=%-embed-libs) MOD_SUBDIRS_MENUSELECT_TREE:=$(MOD_SUBDIRS:%=%-menuselect-tree) ifneq ($(findstring darwin,$(OSARCH)),) @@ -344,39 +344,14 @@ ifeq ($(filter %.menuselect,$(MAKECMDGOALS)),) menuselect/menuselect --check-deps $@ $(GLOBAL_MAKEOPTS) $(USER_MAKEOPTS) endif -$(MOD_SUBDIRS_EMBED_LDSCRIPT): - +@echo "EMBED_LDSCRIPTS+="`$(SILENTMAKE) -C $(@:-embed-ldscript=) SUBDIR=$(@:-embed-ldscript=) __embed_ldscript` >> makeopts.embed_rules - -$(MOD_SUBDIRS_EMBED_LDFLAGS): - +@echo "EMBED_LDFLAGS+="`$(SILENTMAKE) -C $(@:-embed-ldflags=) SUBDIR=$(@:-embed-ldflags=) __embed_ldflags` >> makeopts.embed_rules - -$(MOD_SUBDIRS_EMBED_LIBS): - +@echo "EMBED_LIBS+="`$(SILENTMAKE) -C $(@:-embed-libs=) SUBDIR=$(@:-embed-libs=) __embed_libs` >> makeopts.embed_rules - $(MOD_SUBDIRS_MENUSELECT_TREE): +@$(SUBMAKE) -C $(@:-menuselect-tree=) SUBDIR=$(@:-menuselect-tree=) moduleinfo +@$(SUBMAKE) -C $(@:-menuselect-tree=) SUBDIR=$(@:-menuselect-tree=) makeopts -makeopts.embed_rules: menuselect.makeopts - @echo "Generating embedded module rules ..." - @rm -f $@ - +@$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LDSCRIPT) - +@$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LDFLAGS) - +@$(SUBMAKE) $(MOD_SUBDIRS_EMBED_LIBS) - -$(SUBDIRS): makeopts .lastclean main/version.c include/asterisk/build.h include/asterisk/buildopts.h defaults.h makeopts.embed_rules +$(SUBDIRS): makeopts .lastclean main/version.c include/asterisk/build.h include/asterisk/buildopts.h defaults.h ifeq ($(findstring $(OSARCH), mingw32 cygwin ),) - ifeq ($(shell grep ^MENUSELECT_EMBED=$$ menuselect.makeopts 2>/dev/null),) - # Non-windows: - # ensure that all module subdirectories are processed before 'main' during - # a parallel build, since if there are modules selected to be embedded the - # directories containing them must be completed before the main Asterisk - # binary can be built. - # If MENUSELECT_EMBED is empty, we don't need this and allow 'main' to be - # be built without building all dependencies first. -main: $(filter-out main,$(MOD_SUBDIRS)) - endif +main: third-party else # Windows: we need to build main (i.e. the asterisk dll) first, # followed by res, followed by the other directories, because @@ -441,7 +416,6 @@ distclean: $(SUBDIRS_DIST_CLEAN) _clean @$(MAKE) -C menuselect dist-clean @$(MAKE) -C sounds dist-clean rm -f menuselect.makeopts makeopts menuselect-tree menuselect.makedeps - rm -f makeopts.embed_rules rm -f config.log config.status config.cache rm -rf autom4te.cache rm -f include/asterisk/autoconfig.h @@ -486,7 +460,7 @@ doc/core-en_US.xml: makeopts .lastclean $(XML_core_en_US) @printf "Building Documentation For: " @echo "" > $@ @echo "" >> $@ - @echo "" > $@ + @echo "" >> $@ @echo "" >> $@ @for x in $(MOD_SUBDIRS); do \ printf "$$x " ; \ @@ -510,7 +484,7 @@ else @printf "Building Documentation For: " @echo "" > $@ @echo "" >> $@ - @echo "" > $@ + @echo "" >> $@ @echo "" >> $@ @for x in $(MOD_SUBDIRS); do \ printf "$$x " ; \ @@ -565,7 +539,8 @@ INSTALLDIRS="$(ASTLIBDIR)" "$(ASTMODDIR)" "$(ASTSBINDIR)" "$(ASTETCDIR)" "$(ASTV "$(ASTDATADIR)/documentation/thirdparty" "$(ASTDATADIR)/firmware" \ "$(ASTDATADIR)/firmware/iax" "$(ASTDATADIR)/images" "$(ASTDATADIR)/keys" \ "$(ASTDATADIR)/phoneprov" "$(ASTDATADIR)/rest-api" "$(ASTDATADIR)/static-http" \ - "$(ASTDATADIR)/sounds" "$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)" + "$(ASTDATADIR)/sounds" "$(ASTDATADIR)/moh" "$(ASTMANDIR)/man8" "$(AGI_DIR)" "$(ASTDBDIR)" \ + "$(ASTDATADIR)/third-party" installdirs: @for i in $(INSTALLDIRS); do \ @@ -608,13 +583,14 @@ ifeq ($(HAVE_DAHDI),1) endif $(SUBDIRS_INSTALL): - +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" $(SUBMAKE) -C $(@:-install=) install + +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTDATADIR="$(ASTDATADIR)" $(SUBMAKE) -C $(@:-install=) install NEWMODS:=$(foreach d,$(MOD_SUBDIRS),$(notdir $(wildcard $(d)/*.so))) OLDMODS=$(filter-out $(NEWMODS) $(notdir $(DESTDIR)$(ASTMODDIR)),$(notdir $(wildcard $(DESTDIR)$(ASTMODDIR)/*.so))) +BADMODS=$(strip $(filter-out $(shell ./build_tools/list_valid_installed_externals),$(OLDMODS))) oldmodcheck: - @if [ -n "$(OLDMODS)" ]; then \ + @if [ -n "$(BADMODS)" ]; then \ echo " WARNING WARNING WARNING" ;\ echo "" ;\ echo " Your Asterisk modules directory, located at" ;\ @@ -624,13 +600,87 @@ oldmodcheck: echo " modules are compatible with this version before" ;\ echo " attempting to run Asterisk." ;\ echo "" ;\ - for f in $(OLDMODS); do \ + for f in $(BADMODS); do \ echo " $$f" ;\ done ;\ echo "" ;\ echo " WARNING WARNING WARNING" ;\ fi +ld-cache-update: +ifneq ($(LDCONFIG),) +ifeq ($(DESTDIR),) # DESTDIR means binary archive creation; ldconfig should be run on postinst + @if [ $${EUID} -eq 0 ] ; then \ + $(LDCONFIG) "$(ASTLIBDIR)/" ; \ + else \ + echo " WARNING WARNING WARNING" ;\ + echo "" ;\ + echo " You cannot rebuild the system linker cache unless you are root. " ;\ + echo " You MUST do one of the following..." ;\ + echo " * Re-run 'make install' as root. " ;\ + echo " * Run 'ldconfig $(ASTLIBDIR)' as root. " ;\ + echo " * Run asterisk with 'LD_LIBRARY_PATH=$(ASTLIBDIR) asterisk' " ;\ + echo "" ;\ + echo " WARNING WARNING WARNING" ;\ + fi +endif +endif + +export _oldlibdir = +export _oldmoddir = +ifeq ($(findstring 64,$(HOST_CPU)),64) + # Strip any trailing '/' so the dir and notdir functions work correctly + _current_libdir = $(patsubst %/,%,$(DESTDIR)$(ASTLIBDIR)) + + # Only process if the paths end in lib64 or lib. + # If we're installing to lib64, check lib for orphans. + # If we're installing to lib, check lib64 for orphans. + # Otherwise, leave _oldlibdir empty. + ifeq ($(notdir $(_current_libdir)),lib64) + _oldlibdir = $(dir $(_current_libdir))lib + else ifeq ($(notdir $(_current_libdir)),lib) + _oldlibdir = $(dir $(_current_libdir))lib64 + endif + + # Strip any trailing '/' so the dir and notdir functions work correctly + _current_moddir = $(patsubst %/,%,$(DESTDIR)$(ASTMODDIR)) + + # Only process if the paths contain /lib64/ or /lib/. + # If we're installing to lib64, check lib for orphans. + # If we're installing to lib, check lib64 for orphans. + # Otherwise, leave _oldmoddir empty. + ifeq ($(findstring /lib64/,$(_current_moddir)),/lib64/) + _oldmoddir = $(subst /lib64/,/lib/,$(_current_moddir)) + else ifeq ($(findstring /lib/,$(_current_moddir)),/lib/) + _oldmoddir = $(subst /lib/,/lib64/,$(_current_moddir)) + endif +endif + +check-old-libdir: + @test -n "$(_oldlibdir)" -a -d "$(_oldlibdir)" || exit 0 ;\ + oldfiles=`find "$(_oldlibdir)" -name libasterisk* -print -quit -o \( -path *asterisk/modules/* -a -name *.so \) -print -quit 2>/dev/null` ;\ + if [ "x$$oldfiles" != "x" ] ; then \ + echo " WARNING WARNING WARNING" ;\ + echo "" ;\ + echo " Installation is to: " ;\ + echo " $(DESTDIR)$(ASTLIBDIR)" ;\ + echo " but there are asterisk shared libraries in: " ;\ + echo " $(_oldlibdir)" ;\ + echo " or" ;\ + echo " $(_oldlibdir)/asterisk/modules" ;\ + echo "" ;\ + echo " It is unlikely that asterisk will start." ;\ + echo "" ;\ + echo " You should do one of the following..." ;\ + echo " * Run 'make uninstall' to remove the incorrect libraries" ;\ + echo " then run 'make install' again." ;\ + echo " * Manually remove the libraries from" ;\ + echo " $(_oldlibdir)" ;\ + echo " and run 'ldconfig' to rebuild the linker cache." ;\ + echo "" ;\ + echo " WARNING WARNING WARNING" ;\ + fi + badshell: ifneq ($(filter ~%,$(DESTDIR)),) @echo "Your shell doesn't do ~ expansion when expected (specifically, when doing \"make install DESTDIR=~/path\")." @@ -669,6 +719,8 @@ install: badshell bininstall datafiles @echo " + doxygen installed on your local system +" @echo " +-------------------------------------------+" @$(MAKE) -s oldmodcheck + @$(MAKE) -s ld-cache-update + @$(MAKE) -s check-old-libdir isntall: install @@ -818,60 +870,56 @@ install-logrotate: rm -f contrib/scripts/asterisk.logrotate.tmp config: - @if [ "${OSARCH}" = "linux-gnu" -o "${OSARCH}" = "kfreebsd-gnu" ]; then \ - if [ -f /etc/redhat-release -o -f /etc/fedora-release ]; then \ - ./build_tools/install_subst contrib/init.d/rc.redhat.asterisk "$(DESTDIR)/etc/rc.d/init.d/asterisk"; \ - if [ ! -f "$(DESTDIR)/etc/sysconfig/asterisk" ] ; then \ - $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ - fi ; \ - if [ -z "$(DESTDIR)" ] ; then \ - /sbin/chkconfig --add asterisk ; \ - fi ; \ - elif [ -f /etc/debian_version ] ; then \ - ./build_tools/install_subst contrib/init.d/rc.debian.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ - if [ ! -f "$(DESTDIR)/etc/default/asterisk" ] ; then \ - $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/default/asterisk" ; \ - fi ; \ - if [ -z "$(DESTDIR)" ] ; then \ - /usr/sbin/update-rc.d asterisk defaults 50 91 ; \ - fi ; \ - elif [ -f /etc/gentoo-release ] ; then \ - ./build_tools/install_subst contrib/init.d/rc.gentoo.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ - if [ -z "$(DESTDIR)" ] ; then \ - /sbin/rc-update add asterisk default ; \ - fi ; \ - elif [ -f /etc/mandrake-release -o -f /etc/mandriva-release ] ; then \ - ./build_tools/install_subst contrib/init.d/rc.mandriva.asterisk "$(DESTDIR)/etc/rc.d/init.d/asterisk"; \ - if [ ! -f /etc/sysconfig/asterisk ] ; then \ - $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ - fi ; \ - if [ -z "$(DESTDIR)" ] ; then \ - /sbin/chkconfig --add asterisk ; \ - fi ; \ - elif [ -f /etc/SuSE-release -o -f /etc/novell-release ] ; then \ - ./build_tools/install_subst contrib/init.d/rc.suse.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ - if [ ! -f /etc/sysconfig/asterisk ] ; then \ - $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ - fi ; \ - if [ -z "$(DESTDIR)" ] ; then \ - /sbin/chkconfig --add asterisk ; \ - fi ; \ - elif [ -f /etc/arch-release -o -f /etc/arch-release ] ; then \ - ./build_tools/install_subst contrib/init.d/rc.archlinux.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ - elif [ -d "$(DESTDIR)/Library/LaunchDaemons" ]; then \ - if [ ! -f "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.asterisk.plist" ]; then \ - ./build_tools/install_subst contrib/init.d/org.asterisk.asterisk.plist "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.asterisk.plist"; \ - fi; \ - if [ ! -f "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.muted.plist" ]; then \ - ./build_tools/install_subst contrib/init.d/org.asterisk.muted.plist "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.muted.plist"; \ - fi; \ - elif [ -f /etc/slackware-version ]; then \ - echo "Slackware is not currently supported, although an init script does exist for it."; \ - else \ - echo "We could not install init scripts for your distribution." ; \ - fi \ + @if [ -f /etc/redhat-release -o -f /etc/fedora-release ]; then \ + ./build_tools/install_subst contrib/init.d/rc.redhat.asterisk "$(DESTDIR)/etc/rc.d/init.d/asterisk"; \ + if [ ! -f "$(DESTDIR)/etc/sysconfig/asterisk" ] ; then \ + $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ + fi ; \ + if [ -z "$(DESTDIR)" ] ; then \ + /sbin/chkconfig --add asterisk ; \ + fi ; \ + elif [ -f /etc/debian_version ] ; then \ + ./build_tools/install_subst contrib/init.d/rc.debian.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ + if [ ! -f "$(DESTDIR)/etc/default/asterisk" ] ; then \ + $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/default/asterisk" ; \ + fi ; \ + if [ -z "$(DESTDIR)" ] ; then \ + /usr/sbin/update-rc.d asterisk defaults 50 91 ; \ + fi ; \ + elif [ -f /etc/gentoo-release ] ; then \ + ./build_tools/install_subst contrib/init.d/rc.gentoo.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ + if [ -z "$(DESTDIR)" ] ; then \ + /sbin/rc-update add asterisk default ; \ + fi ; \ + elif [ -f /etc/mandrake-release -o -f /etc/mandriva-release ] ; then \ + ./build_tools/install_subst contrib/init.d/rc.mandriva.asterisk "$(DESTDIR)/etc/rc.d/init.d/asterisk"; \ + if [ ! -f /etc/sysconfig/asterisk ] ; then \ + $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ + fi ; \ + if [ -z "$(DESTDIR)" ] ; then \ + /sbin/chkconfig --add asterisk ; \ + fi ; \ + elif [ -f /etc/SuSE-release -o -f /etc/novell-release ] ; then \ + ./build_tools/install_subst contrib/init.d/rc.suse.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ + if [ ! -f /etc/sysconfig/asterisk ] ; then \ + $(INSTALL) -m 644 contrib/init.d/etc_default_asterisk "$(DESTDIR)/etc/sysconfig/asterisk" ; \ + fi ; \ + if [ -z "$(DESTDIR)" ] ; then \ + /sbin/chkconfig --add asterisk ; \ + fi ; \ + elif [ -f /etc/arch-release -o -f /etc/arch-release ] ; then \ + ./build_tools/install_subst contrib/init.d/rc.archlinux.asterisk "$(DESTDIR)/etc/init.d/asterisk"; \ + elif [ -d "$(DESTDIR)/Library/LaunchDaemons" ]; then \ + if [ ! -f "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.asterisk.plist" ]; then \ + ./build_tools/install_subst contrib/init.d/org.asterisk.asterisk.plist "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.asterisk.plist"; \ + fi; \ + if [ ! -f "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.muted.plist" ]; then \ + ./build_tools/install_subst contrib/init.d/org.asterisk.muted.plist "$(DESTDIR)/Library/LaunchDaemons/org.asterisk.muted.plist"; \ + fi; \ + elif [ -f /etc/slackware-version ]; then \ + echo "Slackware is not currently supported, although an init script does exist for it."; \ else \ - echo "We could not install init scripts for your operating system." ; \ + echo "We could not install init scripts for your distribution." ; \ fi sounds: @@ -886,13 +934,14 @@ sounds: @[ -f "$(DESTDIR)$(ASTDBDIR)/astdb.sqlite3" ] || [ ! -f "$(DESTDIR)$(ASTDBDIR)/astdb" ] || [ ! -f menuselect.makeopts ] || grep -q MENUSELECT_UTILS=.*astdb2sqlite3 menuselect.makeopts || (sed -i.orig -e's/MENUSELECT_UTILS=\(.*\)/MENUSELECT_UTILS=\1 astdb2sqlite3/' menuselect.makeopts && echo "Updating menuselect.makeopts to include astdb2sqlite3" && echo "Original version backed up to menuselect.makeopts.orig") $(SUBDIRS_UNINSTALL): - +@$(SUBMAKE) -C $(@:-uninstall=) uninstall + +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTDATADIR="$(ASTDATADIR)" $(SUBMAKE) -C $(@:-uninstall=) uninstall main-binuninstall: +@DESTDIR="$(DESTDIR)" ASTSBINDIR="$(ASTSBINDIR)" ASTLIBDIR="$(ASTLIBDIR)" $(SUBMAKE) -C main binuninstall _uninstall: $(SUBDIRS_UNINSTALL) main-binuninstall rm -f "$(DESTDIR)$(ASTMODDIR)/"* + test -n "$(_oldmoddir)" -a -d "$(_oldmoddir)" && rm -f "$(_oldmoddir)/"* || : rm -f "$(DESTDIR)$(ASTSBINDIR)/astgenkey" rm -f "$(DESTDIR)$(ASTSBINDIR)/autosupport" rm -rf "$(DESTDIR)$(ASTHEADERDIR)" @@ -905,6 +954,9 @@ ifeq ($(HAVE_DAHDI),1) rm -f $(DESTDIR)$(DAHDI_UDEV_HOOK_DIR)/40-asterisk endif $(MAKE) -C sounds uninstall +ifneq ($(LDCONFIG),) + $(LDCONFIG) || : +endif uninstall: _uninstall @echo " +--------- Asterisk Uninstall Complete -----+" @@ -922,6 +974,7 @@ uninstall: _uninstall uninstall-all: _uninstall rm -rf "$(DESTDIR)$(ASTMODDIR)" + test -n "$(_oldmoddir)" -a -d "$(_oldmoddir)" && rm -rf "$(_oldmoddir)" || : rm -rf "$(DESTDIR)$(ASTVARLIBDIR)" rm -rf "$(DESTDIR)$(ASTDATADIR)" rm -rf "$(DESTDIR)$(ASTSPOOLDIR)" @@ -978,7 +1031,7 @@ menuselect/nmenuselect: menuselect/makeopts .lastclean menuselect/makeopts: makeopts .lastclean +$(MAKE_MENUSELECT) makeopts -menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml build_tools/embed_modules.xml utils/utils.xml agi/agi.xml configure makeopts +menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(dir)/*.c) $(wildcard $(dir)/*.cc) $(wildcard $(dir)/*.xml)) build_tools/cflags.xml build_tools/cflags-devmode.xml sounds/sounds.xml utils/utils.xml agi/agi.xml configure makeopts @echo "Generating input for menuselect ..." @echo "" > $@ @echo >> $@ @@ -991,7 +1044,6 @@ menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(di fi @cat utils/utils.xml >> $@ @cat agi/agi.xml >> $@ - @cat build_tools/embed_modules.xml >> $@ @cat sounds/sounds.xml >> $@ @echo "" >> $@ @@ -1009,6 +1061,10 @@ else rest-api/resources.json . endif +check-alembic: makeopts + @find contrib/ast-db-manage/ -name '*.pyc' -delete + @ALEMBIC=$(ALEMBIC) build_tools/make_check_alembic config cdr voicemail >&2 + .PHONY: menuselect .PHONY: main .PHONY: sounds @@ -1030,14 +1086,14 @@ endif .PHONY: _clean .PHONY: ari-stubs .PHONY: basic-pbx +.PHONY: check-alembic +.PHONY: ld-cache-update +.PHONY: check-old-libdir .PHONY: $(SUBDIRS_INSTALL) .PHONY: $(SUBDIRS_DIST_CLEAN) .PHONY: $(SUBDIRS_CLEAN) .PHONY: $(SUBDIRS_UNINSTALL) .PHONY: $(SUBDIRS) -.PHONY: $(MOD_SUBDIRS_EMBED_LDSCRIPT) -.PHONY: $(MOD_SUBDIRS_EMBED_LDFLAGS) -.PHONY: $(MOD_SUBDIRS_EMBED_LIBS) FORCE: diff --git a/Makefile.moddir_rules b/Makefile.moddir_rules index df715d9875d..59190bece9a 100644 --- a/Makefile.moddir_rules +++ b/Makefile.moddir_rules @@ -18,10 +18,6 @@ # Also note that we can only set one variable per rule, so we have to # repeat the left hand side to set multiple variables. -ifeq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),) - _ASTCFLAGS+=${GC_CFLAGS} -endif - ifneq ($(findstring STATIC_BUILD,$(MENUSELECT_CFLAGS)),) STATIC_BUILD=-static endif @@ -29,7 +25,7 @@ endif include $(ASTTOPDIR)/Makefile.rules # If MODULE_PREFIX is defined, use it to run the standard functions to set -# C_MODS, CC_MODS, LOADABLE_MODS and EMBEDDED_MODS. +# C_MODS, CC_MODS and LOADABLE_MODS # Each word of MODULE_PREFIX is a prefix for filenames that we consider # valid C or CC modules (eg. app, func ...). Note that the underscore # is added here, and does not need to be in MODULE_PREFIX @@ -46,11 +42,7 @@ endif C_MODS:=$(filter-out $(MENUSELECT_$(MENUSELECT_CATEGORY)),$(ALL_C_MODS)) CC_MODS:=$(filter-out $(MENUSELECT_$(MENUSELECT_CATEGORY)),$(ALL_CC_MODS)) -ifneq ($(findstring EMBED_$(MENUSELECT_CATEGORY),$(MENUSELECT_EMBED)),) - EMBEDDED_MODS:=$(C_MODS) $(CC_MODS) -else - LOADABLE_MODS:=$(C_MODS) $(CC_MODS) -endif +LOADABLE_MODS:=$(C_MODS) $(CC_MODS) # Both C++ and C++ sources need their module name in AST_MODULE # We also pass whatever _INCLUDE list is generated by menuselect @@ -67,7 +59,7 @@ MOD_ASTCFLAGS=\ $(foreach dep,$(MENUSELECT_DEPENDS_$(1)),$(value $(dep)_INCLUDE)) define MOD_ADD_SOURCE -$$(if $$(filter $(1),$$(EMBEDDED_MODS)),modules.link,$(1).so): $$(subst $(3),$(5),$(2)) +$(1).so: $$(subst $(3),$(5),$(2)) $$(subst $(3),$(5),$(2)): _ASTCFLAGS+=$$(call MOD_ASTCFLAGS,$(1)) .$(1).moduleinfo: MODULEINFO_EXTRA_OUTPUT=" $$(addprefix $$(SUBDIR)/,$$(subst $(3),$(5),$(2)) $$(subst $(3),$(4),$(2)))" # The use of wildcard ensures that 'make menuselect' will not fail for modules that @@ -77,7 +69,7 @@ $$(subst $(3),$(5),$(2)): _ASTCFLAGS+=$$(call MOD_ASTCFLAGS,$(1)) clean:: clean-$(1)$(3) clean-$(1)$(3): - rm -f $$(subst $(3),$(5),$(2)) $$(subst $(3),$(4),$(2)) + rm -f $$(subst $(3),$(4),$(2)) $$(subst $(3),$(5),$(2)) $$(subst $(3),$(6),$(2)) $$(subst $(3),$(7),$(2)) endef @@ -96,16 +88,11 @@ endif $(LOADABLE_MODS:%=%.so): LIBS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LIB)) $(LOADABLE_MODS:%=%.so): _ASTLDFLAGS+=$(foreach dep,$(MENUSELECT_DEPENDS_$*),$(value $(dep)_LDFLAGS)) -$(EMBEDDED_MODS:%=%.o): _ASTCFLAGS+=-DEMBEDDED_MODULE=$* - $(addsuffix .so,$(filter $(LOADABLE_MODS),$(C_MODS))): %.so: %.o $(addsuffix .so,$(filter $(LOADABLE_MODS),$(CC_MODS))): %.so: %.oo -modules.link: $(addsuffix .eo,$(filter $(EMBEDDED_MODS),$(C_MODS))) - .PHONY: clean uninstall _all moduleinfo makeopts -ifneq ($(LOADABLE_MODS),) _all: $(LOADABLE_MODS:%=%.so) ifneq ($(findstring $(OSARCH), mingw32 cygwin ),) # linker options and extra libraries for cygwin @@ -113,28 +100,6 @@ ifneq ($(findstring $(OSARCH), mingw32 cygwin ),) LIBS+=-L$(ASTTOPDIR)/main -lasterisk -L$(ASTTOPDIR)/res $($@_LIBS) # additional libraries in res/ endif -endif - -ifneq ($(EMBEDDED_MODS),) -_all: modules.link -__embed_ldscript: - @echo "../$(SUBDIR)/modules.link" -__embed_ldflags: - @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(C_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LDFLAGS))" - @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(CC_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LDFLAGS))" -__embed_libs: - @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(C_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LIB))" - @echo "$(foreach mod,$(filter $(EMBEDDED_MODS),$(CC_MODS)),$(foreach dep,$(MENUSELECT_DEPENDS_$(mod)),$(dep)_LIB))" -else -__embed_ldscript: -__embed_ldflags: -__embed_libs: -endif - -modules.link: - @rm -f $@ - @for file in $(patsubst %,$(SUBDIR)/%,$(filter %.eo,$^)); do echo "INPUT (../$${file})" >> $@; done - @for file in $(patsubst %,$(SUBDIR)/%,$(filter-out %.eo,$^)); do echo "INPUT (../$${file})" >> $@; done clean:: rm -f *.so *.o *.oo *.eo *.i *.ii @@ -146,6 +111,18 @@ clean:: install:: all @echo "Installing modules from `basename $(CURDIR)`..." @for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x "$(DESTDIR)$(ASTMODDIR)" ; done +ifneq ($(findstring :,$(XMLSTARLET)$(BASH)),:) + @if [ -f .moduleinfo ] ; then \ + declare -A DISABLED_MODS ;\ + for x in $(MENUSELECT_$(MENUSELECT_CATEGORY)) ; do DISABLED_MODS[$${x}]=1 ; done ;\ + EXTERNAL_MODS=$$(xmlstarlet sel -t -m "/category/member[support_level = 'external']" -v "@name" -n .moduleinfo) ;\ + for x in $${EXTERNAL_MODS} ; do \ + if [ -z "$${DISABLED_MODS[$${x}]}" ] ; then \ + $(ASTTOPDIR)/build_tools/download_externals $${x} ;\ + fi ;\ + done ;\ + fi +endif uninstall:: @@ -164,8 +141,8 @@ dist-clean:: $(AWK) -f $(ASTTOPDIR)/build_tools/get_moduleinfo $^ >> $@ echo "" >> $@ -.moduleinfo:: $(addsuffix .moduleinfo,$(addprefix .,$(sort $(ALL_C_MODS) $(ALL_CC_MODS)))) - @echo "" > $@ +.moduleinfo:: $(addsuffix .moduleinfo,$(addprefix .,$(sort $(ALL_C_MODS) $(ALL_CC_MODS)))) $(wildcard $(call tolower,$(MENUSELECT_CATEGORY)).xml) + @echo "" > $@ @cat $^ >> $@ @echo "" >> $@ diff --git a/Makefile.rules b/Makefile.rules index 1031f2defe3..ee8eabd6f87 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -17,6 +17,10 @@ -include $(ASTTOPDIR)/makeopts +# Helpful functions +# call with $(call function,...) +tolower = $(shell echo $(1) | tr '[:upper:]' '[:lower:]') + .PHONY: dist-clean # If 'make' decides to create intermediate files to satisfy a build requirement @@ -103,13 +107,15 @@ CC_LIBS=$(PTHREAD_LIBS) $(LIBS) CXX_LIBS=$(PTHREAD_LIBS) $(LIBS) # determine whether to double-compile so that the optimizer can report code path problems -# this is only done when developer mode and DONT_OPTIMIZE are both enabled -# in that case, we run the preprocessor to produce a .i or .ii file from the source +# In this case, we run the preprocessor to produce a .i or .ii file from the source # code, then compile once with optimizer enabled (and the output to /dev/null), # and if that doesn't fail then compile again with optimizer disabled -ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS))$(AST_DEVMODE),DONT_OPTIMIZEyes) + +ifeq ($(findstring COMPILE_DOUBLE,$(MENUSELECT_CFLAGS)),COMPILE_DOUBLE) COMPILE_DOUBLE=yes -else +endif + +ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS))$(AST_DEVMODE),) _ASTCFLAGS+=$(AST_FORTIFY_SOURCE) endif @@ -179,18 +185,6 @@ endif $(ECHO_PREFIX) echo " [LDXX] $^ -> $@" $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(CXX_LDFLAGS_SO) $^ $(CXX_LIBS) -%.eo: %.o - $(ECHO_PREFIX) echo " [EMBED] $< -> $@" - $(CMD_PREFIX) $(ASTTOPDIR)/build_tools/make_linker_eo_script $* > .$@.ld - $(CMD_PREFIX) $(LD) -r -T .$@.ld -o $@ $< - $(CMD_PREFIX) rm -f .$@.ld - -%.eo: %.oo - $(ECHO_PREFIX) echo " [EMBED] $< -> $@" - $(CMD_PREFIX) $(ASTTOPDIR)/build_tools/make_linker_eo_script $* > .$@.ld - $(CMD_PREFIX) $(LD) -r -T .$@.ld -o $@ $< - $(CMD_PREFIX) rm -f .$@.ld - %: %.o $(ECHO_PREFIX) echo " [LD] $^ -> $@" $(CMD_PREFIX) $(CXX) $(STATIC_BUILD) -o $@ $(PTHREAD_CFLAGS) $(_ASTLDFLAGS) $^ $(CXX_LIBS) $(ASTLDFLAGS) diff --git a/README b/README index d5f86c1ac5e..10f2824fdda 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ === by Mark Spencer === and the Asterisk.org developer community === -=== Copyright (C) 2001-2009 Digium, Inc. +=== Copyright (C) 2001-2016 Digium, Inc. === and other copyright holders. =============================================================================== diff --git a/README-SERIOUSLY.bestpractices.txt b/README-SERIOUSLY.bestpractices.txt index b6b418d9fae..0d3e670cf24 100644 --- a/README-SERIOUSLY.bestpractices.txt +++ b/README-SERIOUSLY.bestpractices.txt @@ -94,6 +94,13 @@ your ITSP in a place where you didn't expect to allow it. There are a couple of ways in which you can mitigate this impact: stricter pattern matching, or using the FILTER() dialplan function. +The CALLERID(num) and CALLERID(name) values are other commonly used values that +are sources of data potentially supplied by outside sources. If you use these +values as parameters to the System(), MixMonitor(), or Monitor() applications +or the SHELL() dialplan function, you can allow injection of arbitrary operating +system command execution. The FILTER() dialplan function is available to remove +dangerous characters from untrusted strings to block the command injection. + Strict Pattern Matching ----------------------- diff --git a/UPGRADE-14.txt b/UPGRADE-14.txt new file mode 100644 index 00000000000..aaf236ba23c --- /dev/null +++ b/UPGRADE-14.txt @@ -0,0 +1,115 @@ +=========================================================== +=== +=== Information for upgrading between Asterisk versions +=== +=== These files document all the changes that MUST be taken +=== into account when upgrading between the Asterisk +=== versions listed below. These changes may require that +=== you modify your configuration files, dialplan or (in +=== some cases) source code if you have your own Asterisk +=== modules or patches. These files also include advance +=== notice of any functionality that has been marked as +=== 'deprecated' and may be removed in a future release, +=== along with the suggested replacement functionality. +=== +=== UPGRADE-1.2.txt -- Upgrade info for 1.0 to 1.2 +=== UPGRADE-1.4.txt -- Upgrade info for 1.2 to 1.4 +=== UPGRADE-1.6.txt -- Upgrade info for 1.4 to 1.6 +=== UPGRADE-1.8.txt -- Upgrade info for 1.6 to 1.8 +=== UPGRADE-10.txt -- Upgrade info for 1.8 to 10 +=== UPGRADE-11.txt -- Upgrade info for 10 to 11 +=== UPGRADE-12.txt -- Upgrade info for 11 to 12 +=== UPGRADE-13.txt -- Upgrade info for 12 to 13 +=========================================================== + +From 14.6.0 to 14.7.0: + +Core: + - ast_app_parse_timelen now returns an error if it encounters extra characters + at the end of the string to be parsed. + +From 14.4.0 to 14.5.0: + +Core: + - Support for embedded modules has been removed. This has not worked in + many years. LOADABLE_MODULES menuselect option is also removed as + loadable module support is now always enabled. + +From 14.3.0 to 14.4.0: + +res_rtp_asterisk: + - The RTP layer of Asterisk now has support for RFC 5761: "Multiplexing RTP + Data and Control Packets on a Single Port." For the PJSIP channel driver, + chan_pjsip, you can set "rtcp_mux = yes" on a PJSIP endpoint in pjsip.conf + to enable the feature. For chan_sip you can set "rtcp_mux = yes" either + globally or on a per-peer basis in sip.conf. + +New in 14.0.0 + +ARI: + - The policy for when to send "Dial" events has changed. Previously, "Dial" + events were sent on the calling channel's topic. However, starting in Asterisk + 14, if there is no calling channel on which to send the event, the event is + instead sent on the called channel's topic. Note that for the ARI channels + resource's dial operation, this means that the "Dial" events will always be + sent on the called channel's topic. + +Channel Drivers: + +chan_dahdi: + - For users using the FXO port (FXS signaling) distinctive ring detection + feature, you will need to adjust the dringX count values. The count + values now only record ring end events instead of any DAHDI event. A + ring-ring-ring pattern would exceed the pattern limits and stop + Caller-ID detection. + +chan_sip: + - The SIP dial string has been extended past the [!dnid] option by another + exclamation mark: [!dnid[!fromuri]. An exclamation mark in the To-URI + will now mean changes to the From-URI. + +Core: + - The REF_DEBUG compiler flag is now used to enable refdebug by default. + The setting can be overridden in asterisk.conf by setting refdebug in + the options category. No recompile is required to enable/disable it. + + - Modified processing of command-line options to first parse only what + is necessary to read asterisk.conf. Once asterisk.conf is fully loaded, + the remaining options are processed. The -X option now applies to + asterisk.conf only. To enable #exec for other config files you must + set execincludes=yes in asterisk.conf. Any other option set on the + command-line will now override the equivalent setting from asterisk.conf. + +AMI: + - The 'ModuleCheck' Action's Version key will no longer show the module + version. The value will always be blank. + +CLI: + - The 'core show file version' command has been removed. When Asterisk + moved to Git, the source control version support was removed. As a + result, the CLi command was no longer useful and was removed as well. + +Logging: + - The first callid created is now 1 instead of 0. The value 0 + is now reserved to represent a lack of callid. + +AMI: + - The Command action now sends the output from the CLI command as a series + of Output headers for each line instead of as a block of text with the + --END COMMAND-- delimiter to match the output from other actions. + + Commands that fail to execute (no such command, invalid syntax etc.) now + return an Error response instead of Success. + +app_amd: + - The 'maximum_number_of_words' configuration option and parameter to the AMD + application previously did not match the documented functionality + variable + name. In Asterisk 13, a value of '3' would mean that if '3' words were detected, + the result would be detection as a 'MACHINE'. As of this version, the value + reflects the maximum words that if EXCEEDED (rather than reached), would + result in detection as a machine. This means that you should update this + value to be one higher than your previos value, if your previous value + was working well for you. + +=========================================================== +=========================================================== diff --git a/UPGRADE-15.txt b/UPGRADE-15.txt new file mode 100644 index 00000000000..30dc5d04c74 --- /dev/null +++ b/UPGRADE-15.txt @@ -0,0 +1,40 @@ +=========================================================== +=== +=== Information for upgrading between Asterisk versions +=== +=== These files document all the changes that MUST be taken +=== into account when upgrading between the Asterisk +=== versions listed below. These changes may require that +=== you modify your configuration files, dialplan or (in +=== some cases) source code if you have your own Asterisk +=== modules or patches. These files also include advance +=== notice of any functionality that has been marked as +=== 'deprecated' and may be removed in a future release, +=== along with the suggested replacement functionality. +=== +=== UPGRADE-1.2.txt -- Upgrade info for 1.0 to 1.2 +=== UPGRADE-1.4.txt -- Upgrade info for 1.2 to 1.4 +=== UPGRADE-1.6.txt -- Upgrade info for 1.4 to 1.6 +=== UPGRADE-1.8.txt -- Upgrade info for 1.6 to 1.8 +=== UPGRADE-10.txt -- Upgrade info for 1.8 to 10 +=== UPGRADE-11.txt -- Upgrade info for 10 to 11 +=== UPGRADE-12.txt -- Upgrade info for 11 to 12 +=== UPGRADE-13.txt -- Upgrade info for 12 to 13 +=== UPGRADE-14.txt -- Upgrade info for 13 to 14 +=========================================================== + +New in 15.0.0: + +Build System: + - '--with-pjproject-bundled' is now the default when running ./configure + It can be disabled with '--without-pjproject-bundled'. + +Core: + - Multi-stream support has been added so a channel can have multiple + streams of the same type such as audio and video. + + - The 'Data Retrieval API' has been removed. This API was not actively + maintained, was not added to new modules (such as res_pjsip), and there + exist better alternatives to acquire the same information, such as the + ARI. As a result, the 'DataGet' AMI action as well as the 'data get' + CLI command have been removed. diff --git a/UPGRADE.txt b/UPGRADE.txt index 91d9edc9249..39c0f8cec85 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -20,49 +20,29 @@ === UPGRADE-11.txt -- Upgrade info for 10 to 11 === UPGRADE-12.txt -- Upgrade info for 11 to 12 === UPGRADE-13.txt -- Upgrade info for 12 to 13 +=== UPGRADE-14.txt -- Upgrade info for 13 to 14 +=== UPGRADE-15.txt -- Upgrade info for 14 to 15 =========================================================== -Channel Drivers: +New in 16.0.0: -chan_dahdi: - - For users using the FXO port (FXS signaling) distinctive ring detection - feature, you will need to adjust the dringX count values. The count - values now only record ring end events instead of any DAHDI event. A - ring-ring-ring pattern would exceed the pattern limits and stop - Caller-ID detection. +app_macro: + - The app_macro module is now deprecated and by default it is no longer + built. Users should migrate to app_stack (Gosub). A warning is logged + the first time any Macro is used. -Core: - - The REF_DEBUG compiler flag is now used to enable refdebug by default. - The setting can be overridden in asterisk.conf by setting refdebug in - the options category. No recompile is required to enable/disable it. - - - Modified processing of command-line options to first parse only what - is necessary to read asterisk.conf. Once asterisk.conf is fully loaded, - the remaining options are processed. The -X option now applies to - asterisk.conf only. To enable #exec for other config files you must - set execincludes=yes in asterisk.conf. Any other option set on the - command-line will now override the equivalent setting from asterisk.conf. - -AMI: - - The 'ModuleCheck' Action's Version key will no longer show the module - version. The value will always be blank. - -CLI: - - The 'core show file version' command has been removed. When Asterisk - moved to Git, the source control version support was removed. As a - result, the CLi command was no longer useful and was removed as well. - -Logging: - - The first callid created is now 1 instead of 0. The value 0 - is now reserved to represent a lack of callid. +New in 15.0.0: -AMI: - - The Command action now sends the output from the CLI command as a series - of Output headers for each line instead of as a block of text with the - --END COMMAND-- delimiter to match the output from other actions. +Build System: + - '--with-pjproject-bundled' is now the default when running ./configure + It can be disabled with '--without-pjproject-bundled'. - Commands that fail to execute (no such command, invalid syntax etc.) now - return an Error response instead of Success. - -=========================================================== -=========================================================== +Core: + - Multi-stream support has been added so a channel can have multiple + streams of the same type such as audio and video. + + - The 'Data Retrieval API' has been removed. This API was not actively + maintained, was not added to new modules (such as res_pjsip), and there + exist better alternatives to acquire the same information, such as the + ARI. As a result, the 'DataGet' AMI action as well as the 'data get' + CLI command have been removed. diff --git a/addons/Makefile b/addons/Makefile index a02d35f7d8e..47da132470f 100644 --- a/addons/Makefile +++ b/addons/Makefile @@ -43,10 +43,10 @@ ifeq ($(filter format_mp3,$(MENUSELECT_ADDONS)),) echo ; \ echo "**************************************************************" ; \ echo "*** ***" ; \ - echo "*** ---> READ THIS OR YOUR BUILD WILL FAIL <--- ***" ; \ + echo "*** ---> IMPORTANT INFORMATION ABOUT format_mp3 <--- ***" ; \ echo "*** ***" ; \ echo "*** format_mp3 has been selected to be installed, but the ***" ; \ - echo "*** mp3 decoder library has not yet been downloaded into ***" ; \ + echo "*** MP3 decoder library has not yet been downloaded into ***" ; \ echo "*** the source tree. To do so, please run the following ***" ; \ echo "*** command: ***" ; \ echo "*** ***" ; \ @@ -59,9 +59,13 @@ endif include $(ASTTOPDIR)/Makefile.moddir_rules -$(if $(filter chan_ooh323,$(EMBEDDED_MODS)),modules.link,chan_ooh323.so): _ASTCFLAGS+=$(H323CFLAGS) +chan_ooh323.so: _ASTCFLAGS+=$(H323CFLAGS) $(call MOD_ADD_C,chan_ooh323,$(H323SOURCE)) +ifneq ($(wildcard mp3/Makefile),) $(call MOD_ADD_C,format_mp3,mp3/common.c mp3/dct64_i386.c mp3/decode_ntom.c mp3/layer3.c mp3/tabinit.c mp3/interface.c) .PHONY: check_mp3 +else +.PHONY: check_mp3 format_mp3.o format_mp3.so +endif diff --git a/addons/cdr_mysql.c b/addons/cdr_mysql.c index d55f9e035fc..1f973625191 100644 --- a/addons/cdr_mysql.c +++ b/addons/cdr_mysql.c @@ -42,8 +42,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include @@ -119,7 +117,9 @@ static char *handle_cli_cdr_mysql_status(struct ast_cli_entry *e, int cmd, struc return CLI_SHOWUSAGE; if (connected) { - char status[256], status2[100] = ""; + char status[256]; + char status2[100] = ""; + char buf[362]; /* 256+100+" for "+NULL */ int ctime = time(NULL) - connect_time; if (dbport) snprintf(status, 255, "Connected to %s@%s, port %d", ast_str_buffer(dbname), ast_str_buffer(hostname), dbport); @@ -132,17 +132,10 @@ static char *handle_cli_cdr_mysql_status(struct ast_cli_entry *e, int cmd, struc snprintf(status2, 99, " with username %s", ast_str_buffer(dbuser)); if (ast_str_strlen(dbtable)) snprintf(status2, 99, " using table %s", ast_str_buffer(dbtable)); - if (ctime > 31536000) { - ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 31536000, (ctime % 31536000) / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); - } else if (ctime > 86400) { - ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); - } else if (ctime > 3600) { - ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, ctime / 3600, (ctime % 3600) / 60, ctime % 60); - } else if (ctime > 60) { - ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, ctime % 60); - } else { - ast_cli(a->fd, "%s%s for %d seconds.\n", status, status2, ctime); - } + + snprintf(buf, sizeof(buf), "%s%s for ", status, status2); + ast_cli_print_timestr_fromseconds(a->fd, ctime, buf); + if (records == totalrecords) ast_cli(a->fd, " Wrote %d records since last restart.\n", totalrecords); else @@ -250,7 +243,7 @@ static int mysql_log(struct ast_cdr *cdr) struct ast_tm tm; char timestr[128]; ast_localtime(&tv, &tm, ast_str_strlen(cdrzone) ? ast_str_buffer(cdrzone) : NULL); - ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %T", &tm); + ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); value = ast_strdupa(timestr); cdrname = "calldate"; } else { @@ -265,10 +258,7 @@ static int mysql_log(struct ast_cdr *cdr) /* Need the type and value to determine if we want the raw value or not */ if (entry->staticvalue) { value = ast_strdupa(entry->staticvalue); - } else if ((!strcmp(cdrname, "start") || - !strcmp(cdrname, "answer") || - !strcmp(cdrname, "end") || - !strcmp(cdrname, "disposition") || + } else if ((!strcmp(cdrname, "disposition") || !strcmp(cdrname, "amaflags")) && (strstr(entry->type, "int") || strstr(entry->type, "dec") || @@ -278,6 +268,13 @@ static int mysql_log(struct ast_cdr *cdr) strstr(entry->type, "numeric") || strstr(entry->type, "fixed"))) { ast_cdr_format_var(cdr, cdrname, &value, workspace, sizeof(workspace), 1); + } else if (!strcmp(cdrname, "start") || !strcmp(cdrname, "answer") || + !strcmp(cdrname, "end")) { + struct ast_tm tm; + char timestr[128]; + ast_localtime(&cdr->start, &tm, ast_str_strlen(cdrzone) ? ast_str_buffer(cdrzone) : NULL); + ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); + value = ast_strdupa(timestr); } else if (!strcmp(cdrname, "calldate")) { /* Skip calldate - the value has already been dup'd */ } else { @@ -353,9 +350,20 @@ static int mysql_log(struct ast_cdr *cdr) return 0; } -static int my_unload_module(int reload) -{ +static void free_strings(void) +{ struct unload_string *us; + + AST_LIST_LOCK(&unload_strings); + while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) { + ast_free(us->str); + ast_free(us); + } + AST_LIST_UNLOCK(&unload_strings); +} + +static int my_unload_module(int reload) +{ struct column *entry; ast_cli_unregister_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry)); @@ -366,12 +374,7 @@ static int my_unload_module(int reload) records = 0; } - AST_LIST_LOCK(&unload_strings); - while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) { - ast_free(us->str); - ast_free(us); - } - AST_LIST_UNLOCK(&unload_strings); + free_strings(); if (!reload) { AST_RWLIST_WRLOCK(&columns); @@ -513,7 +516,9 @@ static int my_load_module(int reload) AST_RWLIST_UNLOCK(&columns); } ast_config_destroy(cfg); - return AST_MODULE_LOAD_FAILURE; + free_strings(); + + return AST_MODULE_LOAD_DECLINE; } /* Check for any aliases */ @@ -584,7 +589,9 @@ static int my_load_module(int reload) connected = 0; AST_RWLIST_UNLOCK(&columns); ast_config_destroy(cfg); - return AST_MODULE_LOAD_FAILURE; + free_strings(); + + return AST_MODULE_LOAD_DECLINE; } if (!(result = mysql_store_result(&mysql))) { @@ -593,7 +600,9 @@ static int my_load_module(int reload) connected = 0; AST_RWLIST_UNLOCK(&columns); ast_config_destroy(cfg); - return AST_MODULE_LOAD_FAILURE; + free_strings(); + + return AST_MODULE_LOAD_DECLINE; } while ((row = mysql_fetch_row(result))) { @@ -659,7 +668,8 @@ static int my_load_module(int reload) AST_RWLIST_UNLOCK(&columns); ast_config_destroy(cfg); if (res < 0) { - return AST_MODULE_LOAD_FAILURE; + my_unload_module(0); + return AST_MODULE_LOAD_DECLINE; } if (!reload) { @@ -673,7 +683,12 @@ static int my_load_module(int reload) res = ast_cli_register_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry)); } - return res; + if (res) { + my_unload_module(0); + return AST_MODULE_LOAD_DECLINE; + } + + return AST_MODULE_LOAD_SUCCESS; } static int load_module(void) diff --git a/addons/chan_mobile.c b/addons/chan_mobile.c index 26056f42092..8f04af75302 100644 --- a/addons/chan_mobile.c +++ b/addons/chan_mobile.c @@ -42,8 +42,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include @@ -902,7 +900,7 @@ static struct ast_channel *mbl_request(const char *type, struct ast_format_cap * } if (ast_format_cap_iscompatible_format(cap, DEVICE_FRAME_FORMAT) == AST_FORMAT_CMP_NOT_EQUAL) { - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_format_cap_get_names(cap, &codec_buf)); *cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED; return NULL; @@ -3855,10 +3853,7 @@ static void *do_monitor_phone(void *data) } if ((at_msg = at_read_full(hfp->rsock, buf, sizeof(buf))) < 0) { - /* XXX gnu specific strerror_r is assummed here, this - * is not really safe. See the strerror(3) man page - * for more info. */ - ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror_r(errno, buf, sizeof(buf)), errno); + ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno); break; } @@ -3995,7 +3990,7 @@ static void *do_monitor_phone(void *data) ast_debug(1, "[%s] error parsing message\n", pvt->id); goto e_cleanup; case AT_READ_ERROR: - ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror_r(errno, buf, sizeof(buf)), errno); + ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno); goto e_cleanup; default: break; @@ -4073,11 +4068,7 @@ static void *do_monitor_headset(void *data) continue; if ((at_msg = at_read_full(pvt->rfcomm_socket, buf, sizeof(buf))) < 0) { - if (strerror_r(errno, buf, sizeof(buf))) - ast_debug(1, "[%s] error reading from device\n", pvt->id); - else - ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, buf, errno); - + ast_debug(1, "[%s] error reading from device: %s (%d)\n", pvt->id, strerror(errno), errno); goto e_cleanup; } ast_debug(1, "[%s] %s\n", pvt->id, buf); @@ -4713,9 +4704,13 @@ static int load_module(void) ast_format_cap_append(mbl_tech.capabilities, DEVICE_FRAME_FORMAT, 0); /* Check if we have Bluetooth, no point loading otherwise... */ dev_id = hci_get_route(NULL); + s = hci_open_dev(dev_id); if (dev_id < 0 || s < 0) { ast_log(LOG_ERROR, "No Bluetooth devices found. Not loading module.\n"); + ao2_ref(mbl_tech.capabilities, -1); + mbl_tech.capabilities = NULL; + hci_close_dev(s); return AST_MODULE_LOAD_DECLINE; } @@ -4723,6 +4718,8 @@ static int load_module(void) if (mbl_load_config()) { ast_log(LOG_ERROR, "Errors reading config file %s. Not loading module.\n", MBL_CONFIG); + ao2_ref(mbl_tech.capabilities, -1); + mbl_tech.capabilities = NULL; return AST_MODULE_LOAD_DECLINE; } @@ -4747,10 +4744,9 @@ static int load_module(void) return AST_MODULE_LOAD_SUCCESS; e_cleanup: - if (sdp_session) - sdp_close(sdp_session); + unload_module(); - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; } AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bluetooth Mobile Device Channel Driver", diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c index aa9cbaffa86..0d5a588b77f 100644 --- a/addons/chan_ooh323.c +++ b/addons/chan_ooh323.c @@ -22,6 +22,54 @@ extended ***/ +/*** DOCUMENTATION + + + + R/W Fax Detect + Returns 0 or 1 + Write yes or no + + + R/W t38support + Returns 0 or 1 + Write yes or no + + + R/0 Returns caller URL + + + R/0 Returns caller h323id + + + R/0 Returns caller dialed digits + + + R/0 Returns caller email + + + R/0 Returns callee email + + + R/0 Returns callee dialed digits + + + R/0 Returns caller URL + + + R/W Get or set the maximum number of call forwards for this channel. + + This number describes the number of times a call may be forwarded by this channel + before the call fails. "Forwards" in this case refers to redirects by phones as well + as calls to local channels. + + Note that this has no relation to the SIP Max-Forwards header. + + + + + ***/ + #include "chan_ooh323.h" #include @@ -576,7 +624,7 @@ static struct ast_channel *ooh323_request(const char *type, struct ast_format_ca const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) { - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); struct ast_channel *chan = NULL; struct ooh323_pvt *p = NULL; struct ooh323_peer *peer = NULL; @@ -1192,7 +1240,7 @@ static int ooh323_write(struct ast_channel *ast, struct ast_frame *f) if (ast_format_cap_iscompatible_format(ast_channel_nativeformats(ast), f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) { if (ast_format_cap_count(ast_channel_nativeformats(ast))) { - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n", ast_format_get_name(f->subclass.format), @@ -1545,7 +1593,7 @@ void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txfra return; } if (gH323Debug) { - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ast_verb(0, "Writeformat before update %s/%s\n", ast_format_get_name(ast_channel_writeformat(p->owner)), ast_format_cap_get_names(ast_channel_nativeformats(p->owner), &codec_buf)); @@ -2114,7 +2162,7 @@ int onNewCallCreated(ooCallData *call) } if (gH323Debug) { - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ast_verb(0, " Outgoing call %s(%s) - Codec prefs - %s\n", p->username?p->username:"NULL", call->callToken, @@ -3133,7 +3181,7 @@ int reload_config(int reload) static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - char ip_port[30]; + char ip_port[64]; struct ooh323_peer *prev = NULL, *peer = NULL; switch (cmd) { @@ -3164,7 +3212,7 @@ static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struc } if (peer) { - sprintf(ip_port, "%s:%d", peer->ip, peer->port); + sprintf(ip_port, "%s:%hu", peer->ip, peer->port); ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name); ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no", peer->h245tunneling?"yes":"no"); @@ -3231,8 +3279,8 @@ static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struc static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ooh323_peer *prev = NULL, *peer = NULL; - struct ast_str *codec_buf = ast_str_alloca(64); - char ip_port[30]; + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); + char ip_port[64]; #define FORMAT "%-15.15s %-15.15s %-23.23s %-s\n" switch (cmd) { @@ -3255,7 +3303,7 @@ static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, stru peer = peerl.peers; while (peer) { ast_mutex_lock(&peer->lock); - snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port); + snprintf(ip_port, sizeof(ip_port), "%s:%hu", peer->ip, peer->port); ast_cli(a->fd, FORMAT, peer->name, peer->accountcode, ip_port, @@ -3370,7 +3418,7 @@ static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struc static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ooh323_user *prev = NULL, *user = NULL; - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); #define FORMAT1 "%-15.15s %-15.15s %-15.15s %-s\n" switch (cmd) { @@ -3504,7 +3552,7 @@ static char *handle_cli_ooh323_show_gk(struct ast_cli_entry *e, int cmd, struct static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { char value[FORMAT_STRING_SIZE]; - struct ast_str *codec_buf = ast_str_alloca(64); + struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN); ooAliases *pAlias = NULL, *pAliasNext = NULL;; switch (cmd) { diff --git a/addons/chan_ooh323.h b/addons/chan_ooh323.h index 89caaff63b2..1279a2246d3 100644 --- a/addons/chan_ooh323.h +++ b/addons/chan_ooh323.h @@ -38,7 +38,6 @@ #include #include #include -#include #include "asterisk/lock.h" #include "asterisk/channel.h" diff --git a/addons/format_mp3.c b/addons/format_mp3.c index 07715b548a1..bb0b20850da 100644 --- a/addons/format_mp3.c +++ b/addons/format_mp3.c @@ -34,8 +34,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "mp3/mpg123.h" #include "mp3/mpglib.h" @@ -120,9 +118,11 @@ static int mp3_squeue(struct ast_filestream *s) res = ftell(s->f); p->sbuflen = fread(p->sbuf, 1, MP3_SCACHE, s->f); - if(p->sbuflen < 0) { - ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", p->sbuflen, strerror(errno)); - return -1; + if (p->sbuflen < MP3_SCACHE) { + if (ferror(s->f)) { + ast_log(LOG_WARNING, "Error while reading MP3 file: %s\n", strerror(errno)); + return -1; + } } res = decodeMP3(&p->mp,p->sbuf,p->sbuflen,p->dbuf,MP3_DCACHE,&p->dbuflen); if(res != MP3_OK) diff --git a/addons/ooh323c/src/Makefile.in b/addons/ooh323c/src/Makefile.in index d3a96024bdb..15b14f7dfde 100644 --- a/addons/ooh323c/src/Makefile.in +++ b/addons/ooh323c/src/Makefile.in @@ -104,7 +104,7 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LIBRARIES = $(noinst_LIBRARIES) -libooh323c_a_AR = $(AR) cru +libooh323c_a_AR = $(AR) cr libooh323c_a_LIBADD = am_libooh323c_a_OBJECTS = ooLogChan.$(OBJEXT) ooUtils.$(OBJEXT) \ ooGkClient.$(OBJEXT) context.$(OBJEXT) ooDateTime.$(OBJEXT) \ diff --git a/addons/ooh323c/src/ooCalls.c b/addons/ooh323c/src/ooCalls.c index 2eefb46481e..26dc63eab6f 100644 --- a/addons/ooh323c/src/ooCalls.c +++ b/addons/ooh323c/src/ooCalls.c @@ -224,7 +224,8 @@ int ooEndCall(OOH323CallData *call) call->callState = OO_CALL_CLEARED; } - if(call->callState == OO_CALL_CLEARED || call->callState == OO_CALL_CLEAR_RELEASESENT) + if(call->callState == OO_CALL_CLEARED || ((strcmp(call->callType, "incoming")) && + call->callState == OO_CALL_CLEAR_RELEASESENT)) { ooCleanCall(call); call->callState = OO_CALL_REMOVED; diff --git a/addons/ooh323c/src/ooGkClient.c b/addons/ooh323c/src/ooGkClient.c index c090796b667..1262f291434 100644 --- a/addons/ooh323c/src/ooGkClient.c +++ b/addons/ooh323c/src/ooGkClient.c @@ -1272,6 +1272,7 @@ int ooGkClientHandleRegistrationConfirm } } pGkClient->state = GkClientRegistered; + pGkClient->rrqRetries = 0; if(pGkClient->callbacks.onReceivedRegistrationConfirm) pGkClient->callbacks.onReceivedRegistrationConfirm(pRegistrationConfirm, gH323ep.aliases); diff --git a/addons/ooh323c/src/ooSocket.c b/addons/ooh323c/src/ooSocket.c index e9087d1fecc..6032dd0aff0 100644 --- a/addons/ooh323c/src/ooSocket.c +++ b/addons/ooh323c/src/ooSocket.c @@ -15,8 +15,6 @@ *****************************************************************************/ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/io.h" #include "asterisk/lock.h" #include "asterisk/utils.h" @@ -386,7 +384,7 @@ int ooSocketAccept (OOSOCKET socket, OOSOCKET *pNewSocket, if (*pNewSocket <= 0) return ASN_E_INVSOCKET; if (destAddr != 0) { - if ((host = ast_sockaddr_stringify_addr(&addr)) != NULL); + if ((host = ast_sockaddr_stringify_addr(&addr)) != NULL) strncpy(destAddr, host, strlen(host)); } if (destPort != 0) diff --git a/addons/ooh323c/src/oochannels.c b/addons/ooh323c/src/oochannels.c index 76f8422a5a5..0501882a9bb 100644 --- a/addons/ooh323c/src/oochannels.c +++ b/addons/ooh323c/src/oochannels.c @@ -679,9 +679,9 @@ int ooProcessCallFDSETsAndTimers if (0 != call->pH245Channel && 0 != call->pH245Channel->sock) { if(ooPDWrite(pfds, nfds, call->pH245Channel->sock)) { - while (call->pH245Channel->outQueue.count>0) { + if (call->pH245Channel->outQueue.count>0) { if (ooSendMsg(call, OOH245MSG) != OO_OK) - break; + OOTRACEERR1("Error in sending h245 message\n"); } } } @@ -699,26 +699,24 @@ int ooProcessCallFDSETsAndTimers { if(ooPDWrite(pfds, nfds, call->pH225Channel->sock)) { - while (call->pH225Channel->outQueue.count>0) + if (call->pH225Channel->outQueue.count>0) { OOTRACEDBGC3("Sending H225 message (%s, %s)\n", call->callType, call->callToken); if (ooSendMsg(call, OOQ931MSG) != OO_OK) - break; + OOTRACEERR1("Error in sending h225 message\n"); } if(call->pH245Channel && call->pH245Channel->outQueue.count>0 && OO_TESTFLAG (call->flags, OO_M_TUNNELING)) { - while (call->pH245Channel->outQueue.count>0) { OOTRACEDBGC3("H245 message needs to be tunneled. " "(%s, %s)\n", call->callType, call->callToken); if (ooSendMsg(call, OOH245MSG) != OO_OK) - break; + OOTRACEERR1("Error in sending h245 message\n"); } - } - } - } + } + } if(ooTimerNextTimeout(&call->timerList, &toNext)) { @@ -1061,11 +1059,6 @@ int ooH2250Receive(OOH323CallData *call) while(total < len) { struct pollfd pfds; - recvLen = ooSocketRecv (call->pH225Channel->sock, message1, len-total); - memcpy(message+total, message1, recvLen); - total = total + recvLen; - - if(total == len) break; /* Complete message is received */ pfds.fd = call->pH225Channel->sock; pfds.events = POLLIN; @@ -1085,8 +1078,9 @@ int ooH2250Receive(OOH323CallData *call) } return OO_FAILED; } - /* If remaining part of the message is not received in 3 seconds - exit */ + + /* exit If remaining part of the message is not received in 3 seconds */ + if(!ooPDRead(&pfds, 1, call->pH225Channel->sock)) { OOTRACEERR3("Error: Incomplete H.2250 message received - clearing " @@ -1099,6 +1093,23 @@ int ooH2250Receive(OOH323CallData *call) } return OO_FAILED; } + + recvLen = ooSocketRecv (call->pH225Channel->sock, message1, len-total); + if (recvLen == 0) { + OOTRACEERR3("Error in read while receiving H.2250 message - " + "clearing call (%s, %s)\n", call->callType, + call->callToken); + ooFreeQ931Message(pctxt, pmsg); + if(call->callState < OO_CALL_CLEAR) + { + call->callEndReason = OO_REASON_TRANSPORTFAILURE; + call->callState = OO_CALL_CLEAR; + } + return OO_FAILED; + } + memcpy(message+total, message1, recvLen); + total = total + recvLen; + } OOTRACEDBGC3("Received Q.931 message: (%s, %s)\n", diff --git a/addons/ooh323c/src/ooq931.c b/addons/ooh323c/src/ooq931.c index cbc4afb0a8a..4d6d9936882 100644 --- a/addons/ooh323c/src/ooq931.c +++ b/addons/ooh323c/src/ooq931.c @@ -2124,9 +2124,6 @@ int ooSendReleaseComplete(OOH323CallData *call) return OO_FAILED; } memset(releaseComplete, 0, sizeof(H225ReleaseComplete_UUIE)); - q931msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent=1; - q931msg->userInfo->h323_uu_pdu.h245Tunneling = OO_TESTFLAG(call->flags, - OO_M_TUNNELING); q931msg->userInfo->h323_uu_pdu.h323_message_body.t = T_H225H323_UU_PDU_h323_message_body_releaseComplete; @@ -2143,8 +2140,6 @@ int ooSendReleaseComplete(OOH323CallData *call) releaseComplete->reason.t = h225ReasonCode; /* Add user-user ie */ - q931msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent=TRUE; - q931msg->userInfo->h323_uu_pdu.h245Tunneling = OO_TESTFLAG (call->flags, OO_M_TUNNELING); q931msg->userInfo->h323_uu_pdu.h323_message_body.t = T_H225H323_UU_PDU_h323_message_body_releaseComplete; diff --git a/addons/res_config_mysql.c b/addons/res_config_mysql.c index a805cb4b4d7..b080d118b86 100644 --- a/addons/res_config_mysql.c +++ b/addons/res_config_mysql.c @@ -30,8 +30,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include @@ -126,7 +124,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd, static char *handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn); static int require_mysql(const char *database, const char *tablename, va_list ap); -static int internal_require(const char *database, const char *table, ...) attribute_sentinel; static struct ast_cli_entry cli_realtime_mysql_status[] = { AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"), @@ -165,16 +162,6 @@ static struct mysql_conn *find_database(const char *database, int for_write) #define release_database(a) ast_mutex_unlock(&(a)->lock) -static int internal_require(const char *database, const char *table, ...) -{ - va_list ap; - int res; - va_start(ap, table); - res = require_mysql(database, table, ap); - va_end(ap); - return res; -} - static void destroy_table(struct tables *table) { struct columns *column; @@ -316,6 +303,11 @@ static char *decode_chunk(char *chunk) return orig; } +#define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE")) + +/* MySQL requires us to escape the escape... yo dawg */ +static char *ESCAPE_CLAUSE = " ESCAPE '\\\\'"; + static struct ast_variable *realtime_mysql(const char *database, const char *table, const struct ast_variable *rt_fields) { struct mysql_conn *dbh; @@ -328,6 +320,7 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab char *stringp; char *chunk; char *op; + char *escape = ""; const struct ast_variable *field = rt_fields; struct ast_variable *var=NULL, *prev=NULL; @@ -358,20 +351,29 @@ static struct ast_variable *realtime_mysql(const char *database, const char *tab /* Create the first part of the query using the first parameter/value pairs we just extracted If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ - if (!strchr(field->name, ' ')) - op = " ="; - else + if (!strchr(field->name, ' ')) { + op = " ="; + } else { op = ""; + if (IS_SQL_LIKE_CLAUSE(field->name)) { + escape = ESCAPE_CLAUSE; + } + } ESCAPE_STRING(buf, field->value); - ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf)); + ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'%s", table, field->name, op, ast_str_buffer(buf), escape); while ((field = field->next)) { - if (!strchr(field->name, ' ')) - op = " ="; - else + escape = ""; + if (!strchr(field->name, ' ')) { + op = " ="; + } else { op = ""; + if (IS_SQL_LIKE_CLAUSE(field->name)) { + escape = ESCAPE_CLAUSE; + } + } ESCAPE_STRING(buf, field->value); - ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf)); + ast_str_append(&sql, 0, " AND %s%s '%s'%s", field->name, op, ast_str_buffer(buf), escape); } ast_debug(1, "MySQL RealTime: Retrieve SQL: %s\n", ast_str_buffer(sql)); @@ -429,6 +431,7 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char char *stringp; char *chunk; char *op; + char *escape = ""; const struct ast_variable *field = rt_fields; struct ast_variable *var = NULL; struct ast_config *cfg = NULL; @@ -475,17 +478,29 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char /* Create the first part of the query using the first parameter/value pairs we just extracted If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ - if (!strchr(field->name, ' ')) + if (!strchr(field->name, ' ')) { op = " ="; - else + } else { op = ""; + if (IS_SQL_LIKE_CLAUSE(field->name)) { + escape = ESCAPE_CLAUSE; + } + } ESCAPE_STRING(buf, field->value); - ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf)); + ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'%s", table, field->name, op, ast_str_buffer(buf), escape); while ((field = field->next)) { - if (!strchr(field->name, ' ')) op = " ="; else op = ""; + escape = ""; + if (!strchr(field->name, ' ')) { + op = " ="; + } else { + op = ""; + if (IS_SQL_LIKE_CLAUSE(field->name)) { + escape = ESCAPE_CLAUSE; + } + } ESCAPE_STRING(buf, field->value); - ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf)); + ast_str_append(&sql, 0, " AND %s%s '%s'%s", field->name, op, ast_str_buffer(buf), escape); } if (initfield) { @@ -508,9 +523,8 @@ static struct ast_config *realtime_multi_mysql(const char *database, const char while ((row = mysql_fetch_row(result))) { var = NULL; - cat = ast_category_new("", "", -1); + cat = ast_category_new_anonymous(); if (!cat) { - ast_log(LOG_WARNING, "Out of memory!\n"); continue; } for (i = 0; i < numFields; i++) { @@ -600,11 +614,6 @@ static int update_mysql(const char *database, const char *tablename, const char ESCAPE_STRING(buf, field->value); ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf)); - /* If the column length isn't long enough, give a chance to lengthen it. */ - if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { - internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL); - } - while ((field = field->next)) { /* If the column is not within the table, then skip it */ if (!(column = find_column(table, field->name))) { @@ -614,11 +623,6 @@ static int update_mysql(const char *database, const char *tablename, const char ESCAPE_STRING(buf, field->value); ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf)); - - /* If the column length isn't long enough, give a chance to lengthen it. */ - if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { - internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL); - } } ESCAPE_STRING(buf, lookup); @@ -703,11 +707,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru ESCAPE_STRING(buf, field->value); ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf)); first = 0; - - /* If the column length isn't long enough, give a chance to lengthen it. */ - if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { - internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL); - } } first = 1; @@ -721,11 +720,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru ESCAPE_STRING(buf, field->value); ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf)); first = 0; - - /* If the column length isn't long enough, give a chance to lengthen it. */ - if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { - internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL); - } } release_table(table); @@ -759,7 +753,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields) { struct mysql_conn *dbh; - my_ulonglong insertid; struct ast_str *sql = ast_str_thread_get(&sql_buf, 16); struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16); struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16); @@ -792,15 +785,11 @@ static int store_mysql(const char *database, const char *table, const struct ast ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name); ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf)); - internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL); - while ((field = field->next)) { ESCAPE_STRING(buf, field->value); - if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) { - ast_str_append(&sql, 0, ", `%s`", field->name); - ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf)); - } + ast_str_append(&sql, 0, ", `%s`", field->name); + ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf)); } ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2)); ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql)); @@ -812,18 +801,11 @@ static int store_mysql(const char *database, const char *table, const struct ast return -1; } - /*!\note The return value is non-portable and may change in future versions. */ - insertid = mysql_insert_id(&dbh->handle); release_database(dbh); - ast_debug(1, "MySQL RealTime: row inserted on table: %s, id: %llu\n", table, insertid); + ast_debug(1, "MySQL RealTime: row inserted on table: %s\n", table); - /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html - * An integer greater than zero indicates the number of rows affected - * Zero indicates that no records were updated - * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.) - */ - return (int)insertid; + return 1; } static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields) @@ -951,8 +933,8 @@ static struct ast_config *config_mysql(const char *database, const char *table, } if (strcmp(last, row[0]) || last_cat_metric != atoi(row[3])) { - if (!(cur_cat = ast_category_new(row[0], "", -1))) { - ast_log(LOG_WARNING, "Out of memory!\n"); + cur_cat = ast_category_new_dynamic(row[0]); + if (!cur_cat) { break; } strcpy(last, row[0]); @@ -989,105 +971,14 @@ static int unload_mysql(const char *database, const char *tablename) return cur ? 0 : -1; } -static int modify_mysql(const char *database, const char *tablename, struct columns *column, require_type type, int len) -{ - /*!\note Cannot use ANY of the same scratch space as is used in other functions, as this one is interspersed. */ - struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *escbuf = ast_str_thread_get(&modify2_buf, 100); - struct ast_str *typestr = ast_str_thread_get(&modify3_buf, 30); - int waschar = strncasecmp(column->type, "char", 4) == 0 ? 1 : 0; - int wasvarchar = strncasecmp(column->type, "varchar", 7) == 0 ? 1 : 0; - int res = 0; - struct mysql_conn *dbh; - - if (!(dbh = find_database(database, 1))) { - return -1; - } - - do { - if (type == RQ_CHAR || waschar || wasvarchar) { - if (wasvarchar) { - ast_str_set(&typestr, 0, "VARCHAR(%d)", len); - } else { - ast_str_set(&typestr, 0, "CHAR(%d)", len); - } - } else if (type == RQ_UINTEGER1) { - ast_str_set(&typestr, 0, "tinyint(3) unsigned"); - } else if (type == RQ_INTEGER1) { - ast_str_set(&typestr, 0, "tinyint(4)"); - } else if (type == RQ_UINTEGER2) { - ast_str_set(&typestr, 0, "smallint(5) unsigned"); - } else if (type == RQ_INTEGER2) { - ast_str_set(&typestr, 0, "smallint(6)"); - } else if (type == RQ_UINTEGER3) { - ast_str_set(&typestr, 0, "mediumint(8) unsigned"); - } else if (type == RQ_INTEGER3) { - ast_str_set(&typestr, 0, "mediumint(8)"); - } else if (type == RQ_UINTEGER4) { - ast_str_set(&typestr, 0, "int(10) unsigned"); - } else if (type == RQ_INTEGER4) { - ast_str_set(&typestr, 0, "int(11)"); - } else if (type == RQ_UINTEGER8) { - ast_str_set(&typestr, 0, "bigint(19) unsigned"); - } else if (type == RQ_INTEGER8) { - ast_str_set(&typestr, 0, "bigint(20)"); - } else if (type == RQ_DATETIME) { - ast_str_set(&typestr, 0, "datetime"); - } else if (type == RQ_DATE) { - ast_str_set(&typestr, 0, "date"); - } else if (type == RQ_FLOAT) { - ast_str_set(&typestr, 0, "FLOAT(%d,2)", len); - } else { - ast_log(LOG_ERROR, "Unknown type (should NEVER happen)\n"); - res = -1; - break; - } - ast_str_set(&sql, 0, "ALTER TABLE %s MODIFY `%s` %s", tablename, column->name, ast_str_buffer(typestr)); - if (!column->null) { - ast_str_append(&sql, 0, " NOT NULL"); - } - if (!ast_strlen_zero(column->dflt)) { - ESCAPE_STRING(escbuf, column->dflt); - ast_str_append(&sql, 0, " DEFAULT '%s'", ast_str_buffer(escbuf)); - } - - if (!mysql_reconnect(dbh)) { - ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql)); - res = -1; - break; - } - - /* Execution. */ - if (mysql_real_query(&dbh->handle, ast_str_buffer(sql), ast_str_strlen(sql))) { - ast_log(LOG_WARNING, "MySQL RealTime: Failed to modify database: %s\n", mysql_error(&dbh->handle)); - ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql)); - res = -1; - } - } while (0); - - release_database(dbh); - return res; -} - -#define PICK_WHICH_ALTER_ACTION(stringtype) \ - if (table->database->requirements == RQ_WARN) { \ - ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ - "the required data length: %d (detected stringtype)\n", \ - tablename, database, column->name, size); \ - res = -1; \ - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { \ - table_altered = 1; \ - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { \ - table_altered = 1; \ - } else { \ - res = -1; \ - } - static int require_mysql(const char *database, const char *tablename, va_list ap) { struct columns *column; struct tables *table = find_table(database, tablename); char *elm; - int type, size, res = 0, table_altered = 0; + int type; + int size; + int res = 0; if (!table) { ast_log(LOG_WARNING, "Table %s not found in database. This table should exist if you're using realtime.\n", tablename); @@ -1097,55 +988,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap while ((elm = va_arg(ap, char *))) { type = va_arg(ap, require_type); size = va_arg(ap, int); + AST_LIST_TRAVERSE(&table->columns, column, list) { if (strcmp(column->name, elm) == 0) { /* Char can hold anything, as long as it is large enough */ if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { if ((size > column->len) && column->len != -1) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len); - res = -1; - } else if (modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else { - res = -1; - } + ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len); + res = -1; } } else if (strcasestr(column->type, "unsigned")) { if (!ast_rq_is_int(type)) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", - database, tablename, column->name, column->type, - type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : - type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink"); - res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { - res = -1; - } + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", + database, tablename, column->name, column->type, + type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : + type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink"); + res = -1; } else if (strncasecmp(column->type, "tinyint", 1) == 0) { if (type != RQ_UINTEGER1) { - PICK_WHICH_ALTER_ACTION(unsigned tinyint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "smallint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) { - PICK_WHICH_ALTER_ACTION(unsigned smallint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "mediumint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER3) { - PICK_WHICH_ALTER_ACTION(unsigned mediumint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "int", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER4) { - PICK_WHICH_ALTER_ACTION(unsigned int) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "bigint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && @@ -1153,45 +1043,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER4 && type != RQ_INTEGER4 && type != RQ_UINTEGER8) { - PICK_WHICH_ALTER_ACTION(unsigned bigint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } } else if (strcasestr(column->type, "int")) { if (!ast_rq_is_int(type)) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", - database, tablename, column->name, column->type, - type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : - type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : - "to get a life, rather than writing silly error messages"); - res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { - res = -1; - } + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", + database, tablename, column->name, column->type, + type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : + type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : + "to get a life, rather than writing silly error messages"); + res = -1; } else if (strncasecmp(column->type, "tinyint", 1) == 0) { if (type != RQ_INTEGER1) { - PICK_WHICH_ALTER_ACTION(tinyint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "smallint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) { - PICK_WHICH_ALTER_ACTION(smallint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "mediumint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_INTEGER3) { - PICK_WHICH_ALTER_ACTION(mediumint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "int", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_INTEGER4) { - PICK_WHICH_ALTER_ACTION(int) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } else if (strncasecmp(column->type, "bigint", 1) == 0) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && @@ -1199,137 +1096,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER4 && type != RQ_INTEGER4 && type != RQ_INTEGER8) { - PICK_WHICH_ALTER_ACTION(bigint) + ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \ + "the required data length: %d (detected stringtype)\n", \ + tablename, database, column->name, size); \ + res = -1; \ } } } else if (strncmp(column->type, "float", 5) == 0) { if (!ast_rq_is_int(type) && type != RQ_FLOAT) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); - res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { - res = -1; - } + ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); + res = -1; } } else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) { if (type != RQ_DATETIME) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); - res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { - res = -1; - } + ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); + res = -1; } } else if (strncmp(column->type, "date", 4) == 0) { if (type != RQ_DATE) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); - res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { - res = -1; - } - } - } else { /* Other, possibly unsupported types? */ - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name); + ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); res = -1; - } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { - table_altered = 1; - } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { - table_altered = 1; - } else { } + } else { /* Other, possibly unsupported types? */ + ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name); + res = -1; } break; } } if (!column) { - if (table->database->requirements == RQ_WARN) { - ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size); - } else { - struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *fieldtype = ast_str_thread_get(&modify3_buf, 16); - - if (table->database->requirements == RQ_CREATECHAR || type == RQ_CHAR) { - ast_str_set(&fieldtype, 0, "CHAR(%d)", size); - } else if (type == RQ_UINTEGER1 || type == RQ_UINTEGER2 || type == RQ_UINTEGER3 || type == RQ_UINTEGER4 || type == RQ_UINTEGER8) { - if (type == RQ_UINTEGER1) { - ast_str_set(&fieldtype, 0, "TINYINT(3) UNSIGNED"); - } else if (type == RQ_UINTEGER2) { - ast_str_set(&fieldtype, 0, "SMALLINT(5) UNSIGNED"); - } else if (type == RQ_UINTEGER3) { - ast_str_set(&fieldtype, 0, "MEDIUMINT(8) UNSIGNED"); - } else if (type == RQ_UINTEGER4) { - ast_str_set(&fieldtype, 0, "INT(10) UNSIGNED"); - } else if (type == RQ_UINTEGER8) { - ast_str_set(&fieldtype, 0, "BIGINT(20) UNSIGNED"); - } else { - ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to squash Tokyo.\n"); - continue; - } - } else if (ast_rq_is_int(type)) { - if (type == RQ_INTEGER1) { - ast_str_set(&fieldtype, 0, "TINYINT(3)"); - } else if (type == RQ_INTEGER2) { - ast_str_set(&fieldtype, 0, "SMALLINT(5)"); - } else if (type == RQ_INTEGER3) { - ast_str_set(&fieldtype, 0, "MEDIUMINT(8)"); - } else if (type == RQ_INTEGER4) { - ast_str_set(&fieldtype, 0, "INT(10)"); - } else if (type == RQ_INTEGER8) { - ast_str_set(&fieldtype, 0, "BIGINT(20)"); - } else { - ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to eat Cincinnati.\n"); - continue; - } - } else if (type == RQ_FLOAT) { - ast_str_set(&fieldtype, 0, "FLOAT"); - } else if (type == RQ_DATE) { - ast_str_set(&fieldtype, 0, "DATE"); - } else if (type == RQ_DATETIME) { - ast_str_set(&fieldtype, 0, "DATETIME"); - } else { - continue; - } - ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, ast_str_buffer(fieldtype)); - - ast_mutex_lock(&table->database->lock); - if (!mysql_reconnect(table->database)) { - ast_mutex_unlock(&table->database->lock); - ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql)); - continue; - } - - /* Execution. */ - if (mysql_real_query(&table->database->handle, ast_str_buffer(sql), ast_str_strlen(sql))) { - ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n"); - ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql)); - ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&table->database->handle)); - } else { - table_altered = 1; - } - } + ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size); } } release_table(table); - /* If we altered the table, we must refresh the cache */ - if (table_altered) { - unload_mysql(database, tablename); - release_table(find_table(database, tablename)); - } return res; } @@ -1518,7 +1319,7 @@ static int load_mysql_config(struct ast_config *config, const char *category, st ast_debug(1, "MySQL RealTime database name: %s\n", conn->name); ast_debug(1, "MySQL RealTime user: %s\n", conn->user); ast_debug(1, "MySQL RealTime password: %s\n", conn->pass); - if(conn->charset) + if(!ast_strlen_zero(conn->charset)) ast_debug(1, "MySQL RealTime charset: %s\n", conn->charset); return 1; @@ -1533,13 +1334,13 @@ static int mysql_reconnect(struct mysql_conn *conn) /* mutex lock should have been locked before calling this function. */ reconnect_tryagain: - if ((!conn->connected) && (!ast_strlen_zero(conn->host) || conn->sock) && !ast_strlen_zero(conn->user) && !ast_strlen_zero(conn->name)) { + if ((!conn->connected) && (!ast_strlen_zero(conn->host) || !ast_strlen_zero(conn->sock)) && !ast_strlen_zero(conn->user) && !ast_strlen_zero(conn->name)) { if (!mysql_init(&conn->handle)) { ast_log(LOG_WARNING, "MySQL RealTime: Insufficient memory to allocate MySQL resource.\n"); conn->connected = 0; return 0; } - if(conn->charset && strlen(conn->charset) > 2){ + if(strlen(conn->charset) > 2){ char set_names[255]; char statement[512]; snprintf(set_names, sizeof(set_names), "SET NAMES %s", conn->charset); diff --git a/apps/Makefile b/apps/Makefile index 7730460fe14..d7f755ff15b 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -29,6 +29,8 @@ include $(ASTTOPDIR)/Makefile.moddir_rules $(call MOD_ADD_C,app_confbridge,$(wildcard confbridge/*.c)) +app_voicemail.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION) + ifneq ($(findstring $(OSARCH), mingw32 cygwin ),) LIBS+= -lres_ael_share.so -lres_monitor.so -lres_speech.so LIBS+= -lres_smdi.so diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c index 3f3d11c257f..6d485d6fb7a 100644 --- a/apps/app_adsiprog.c +++ b/apps/app_adsiprog.c @@ -41,8 +41,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include @@ -1607,7 +1605,7 @@ static int unload_module(void) static int load_module(void) { if (ast_register_application_xml(app, adsi_exec)) - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; return AST_MODULE_LOAD_SUCCESS; } diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c index 68bcfdead8c..bf12b291c80 100644 --- a/apps/app_agent_pool.c +++ b/apps/app_agent_pool.c @@ -33,8 +33,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/cli.h" #include "asterisk/app.h" #include "asterisk/pbx.h" @@ -83,7 +81,7 @@ ASTERISK_REGISTER_FILE() The specified agent is invalid. The agent is already logged in. - The Agents:AgentId device state is + The Agent:AgentId device state is available to monitor the status of the agent. @@ -2655,7 +2653,7 @@ static int load_module(void) agents = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, agent_pvt_sort_cmp, agent_pvt_cmp); if (!agents) { - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; } /* Init agent holding bridge v_table. */ @@ -2679,8 +2677,9 @@ static int load_module(void) res |= ast_register_application_xml(app_agent_request, agent_request_exec); if (res) { + ast_log(LOG_ERROR, "Unable to register application. Not loading module.\n"); unload_module(); - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; } if (load_config()) { diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c index ace4df1dc5f..07885d2bf19 100644 --- a/apps/app_alarmreceiver.c +++ b/apps/app_alarmreceiver.c @@ -45,8 +45,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include #include @@ -977,7 +975,7 @@ static int load_module(void) { if (load_config(0)) { if (ast_register_application_xml(app, alarmreceiver_exec)) { - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; } return AST_MODULE_LOAD_SUCCESS; } diff --git a/apps/app_amd.c b/apps/app_amd.c index ee421b6bc34..25649d4b624 100644 --- a/apps/app_amd.c +++ b/apps/app_amd.c @@ -43,8 +43,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/module.h" #include "asterisk/lock.h" #include "asterisk/channel.h" @@ -62,19 +60,19 @@ ASTERISK_REGISTER_FILE() Is maximum initial silence duration before greeting. - If this is exceeded set as MACHINE + If this is exceeded, the result is detection as a MACHINE is the maximum length of a greeting. - If this is exceeded set as MACHINE + If this is exceeded, the result is detection as a MACHINE Is the silence after detecting a greeting. - If this is exceeded set as HUMAN + If this is exceeded, the result is detection as a HUMAN Is the maximum time allowed for the algorithm - to decide HUMAN or MACHINE + to decide on whether the audio represents a HUMAN, or a MACHINE Is the minimum duration of Voice considered to be a word @@ -85,14 +83,14 @@ ASTERISK_REGISTER_FILE() Is the maximum number of words in a greeting - If this is exceeded set as MACHINE + If this is exceeded, then the result is detection as a MACHINE - How long do we consider silence + What is the average level of noise from 0 to 32767 which if not exceeded, should be considered silence? Is the maximum duration of a word to accept. - If exceeded set as MACHINE + If exceeded, then the result is detection as a MACHINE @@ -130,7 +128,7 @@ ASTERISK_REGISTER_FILE() Word Count - maximum number of words. - + @@ -154,7 +152,7 @@ static int dfltAfterGreetingSilence = 800; static int dfltTotalAnalysisTime = 5000; static int dfltMinimumWordLength = 100; static int dfltBetweenWordsSilence = 50; -static int dfltMaximumNumberOfWords = 3; +static int dfltMaximumNumberOfWords = 2; static int dfltSilenceThreshold = 256; static int dfltMaximumWordLength = 5000; /* Setting this to a large default so it is not used unless specify it in the configs or command line */ @@ -367,7 +365,7 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data) sprintf(amdCause , "MAXWORDLENGTH-%d", consecutiveVoiceDuration); break; } - if (iWordsCount >= maximumNumberOfWords) { + if (iWordsCount > maximumNumberOfWords) { ast_verb(3, "AMD: Channel [%s]. ANSWERING MACHINE: iWordsCount:%d\n", ast_channel_name(chan), iWordsCount); ast_frfree(f); strcpy(amdStatus , "MACHINE"); diff --git a/apps/app_authenticate.c b/apps/app_authenticate.c index f47db45346d..e0ad4a08911 100644 --- a/apps/app_authenticate.c +++ b/apps/app_authenticate.c @@ -31,8 +31,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/lock.h" #include "asterisk/file.h" #include "asterisk/channel.h" @@ -272,7 +270,7 @@ static int unload_module(void) static int load_module(void) { if (ast_register_application_xml(app, auth_exec)) - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; return AST_MODULE_LOAD_SUCCESS; } diff --git a/apps/app_bridgeaddchan.c b/apps/app_bridgeaddchan.c new file mode 100644 index 00000000000..34642a6af9e --- /dev/null +++ b/apps/app_bridgeaddchan.c @@ -0,0 +1,122 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2015, Digium, Inc. + * + * Alec Davis + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Application to place the channel into an existing Bridge + * + * \author Alec Davis + * + * \ingroup applications + */ + +/*** MODULEINFO + core + ***/ + +#include "asterisk.h" + +#include "asterisk/file.h" +#include "asterisk/module.h" +#include "asterisk/channel.h" +#include "asterisk/bridge.h" +#include "asterisk/features.h" + +/*** DOCUMENTATION + + + Join a bridge that contains the specified channel. + + + + Name of the channel in an existing bridge + + + + + This application places the incoming channel into + the bridge containing the specified channel. The specified + channel only needs to be the prefix of a full channel name + IE. 'SIP/cisco0001'. + + + + ***/ + +static const char app[] = "BridgeAdd"; + +static int bridgeadd_exec(struct ast_channel *chan, const char *data) +{ + struct ast_channel *c_ref; + struct ast_bridge_features chan_features; + struct ast_bridge *bridge; + char *c_name; + + /* Answer the channel if needed */ + if (ast_channel_state(chan) != AST_STATE_UP) { + ast_answer(chan); + } + + if (!(c_ref = ast_channel_get_by_name_prefix(data, strlen(data)))) { + ast_log(LOG_WARNING, "Channel %s not found\n", data); + return -1; + } + + c_name = ast_strdupa(ast_channel_name(c_ref)); + + ast_channel_lock(c_ref); + bridge = ast_channel_get_bridge(c_ref); + ast_channel_unlock(c_ref); + + ast_channel_unref(c_ref); + + if (!bridge) { + ast_log(LOG_WARNING, "Channel %s is not in a bridge\n", c_name); + return -1; + } + + ast_verb(3, "%s is joining %s in bridge %s\n", ast_channel_name(chan), + c_name, bridge->uniqueid); + + if (ast_bridge_features_init(&chan_features) + || ast_bridge_join(bridge, chan, NULL, &chan_features, NULL, 0)) { + + ast_log(LOG_WARNING, "%s failed to join %s in bridge %s\n", ast_channel_name(chan), + c_name, bridge->uniqueid); + + ast_bridge_features_cleanup(&chan_features); + ao2_cleanup(bridge); + return -1; + } + + ast_bridge_features_cleanup(&chan_features); + ao2_cleanup(bridge); + return 0; +} + +static int unload_module(void) +{ + return ast_unregister_application(app); +} + +static int load_module(void) +{ + return ast_register_application_xml(app, bridgeadd_exec); +} + +AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Bridge Add Channel Application"); diff --git a/apps/app_bridgewait.c b/apps/app_bridgewait.c index 0e03ad7cecf..b17cddfb2fe 100644 --- a/apps/app_bridgewait.c +++ b/apps/app_bridgewait.c @@ -34,8 +34,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/file.h" #include "asterisk/channel.h" #include "asterisk/pbx.h" diff --git a/apps/app_cdr.c b/apps/app_cdr.c index 7862179f339..1500c89f6c2 100644 --- a/apps/app_cdr.c +++ b/apps/app_cdr.c @@ -31,8 +31,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/channel.h" #include "asterisk/module.h" #include "asterisk/app.h" @@ -251,7 +249,7 @@ static int load_module(void) int res = 0; if (!router) { - return AST_MODULE_LOAD_FAILURE; + return AST_MODULE_LOAD_DECLINE; } res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type); @@ -261,7 +259,8 @@ static int load_module(void) appcdr_callback, NULL); if (res) { - return AST_MODULE_LOAD_FAILURE; + unload_module(); + return AST_MODULE_LOAD_DECLINE; } return AST_MODULE_LOAD_SUCCESS; } diff --git a/apps/app_celgenuserevent.c b/apps/app_celgenuserevent.c index b98cd674db7..67c7fbcbd75 100644 --- a/apps/app_celgenuserevent.c +++ b/apps/app_celgenuserevent.c @@ -29,8 +29,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/module.h" #include "asterisk/app.h" #include "asterisk/channel.h" diff --git a/apps/app_chanisavail.c b/apps/app_chanisavail.c index 0c3b27bb3a2..af4b616f5b0 100644 --- a/apps/app_chanisavail.c +++ b/apps/app_chanisavail.c @@ -33,8 +33,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include "asterisk/lock.h" @@ -56,10 +54,10 @@ static const char app[] = "ChanIsAvail"; Optional extra devices to check - If you need more then one enter them as - Technology2/Resource2&Technology3/Resourse3&..... + If you need more than one enter them as + Technology2/Resource2&Technology3/Resource3&..... - Specification of the device(s) to check. These must be in the format of + Specification of the device(s) to check. These must be in the format of Technology/Resource, where Technology represents a particular channel driver, and Resource represents a resource available to that particular channel driver. diff --git a/apps/app_channelredirect.c b/apps/app_channelredirect.c index 80c1ff03d2b..4f3b79197af 100644 --- a/apps/app_channelredirect.c +++ b/apps/app_channelredirect.c @@ -29,8 +29,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include "asterisk/file.h" #include "asterisk/channel.h" #include "asterisk/pbx.h" diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index 3c7a9171635..95ebace633e 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -35,8 +35,6 @@ #include "asterisk.h" -ASTERISK_REGISTER_FILE() - #include #include @@ -117,6 +115,10 @@ ASTERISK_REGISTER_FILE() either a single group or a colon-delimited list of groups, such as sales:support:accounting. + + + -