2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  1999  -  2006 ,  Digium ,  Inc . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Bluetooth  Mobile  Device  channel  driver 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Dave  Bowerman  < david . bowerman @ gmail . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ ingroup  channel_drivers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-14 21:59:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \li \ref chan_mobile.c uses the configuration file \ref chan_mobile.conf
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ addtogroup  configuration_file  Configuration  Files 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ page  chan_mobile . conf  chan_mobile . conf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ verbinclude  chan_mobile . conf . sample 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< depend > bluetooth < / depend > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< defaultenabled > no < / defaultenabled > 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-14 20:28:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< support_level > extended < / support_level > 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <pthread.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <signal.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/bluetooth.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/hci.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/hci_lib.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/sdp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/sdp_lib.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/rfcomm.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/sco.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <bluetooth/l2cap.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/compat.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/callerid.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/channel.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/logger.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/options.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/linkedlists.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/cli.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/devicestate.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/causes.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/dsp.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/manager.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/io.h" 
  
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/smoother.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/format_cache.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 17:16:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define MBL_CONFIG "chan_mobile.conf" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MBL_CONFIG_OLD "mobile.conf" 
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DEVICE_FRAME_SIZE 48 
  
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEVICE_FRAME_FORMAT ast_format_slin 
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define CHANNEL_FRAME_SIZE 320 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  discovery_interval  =  60 ; 			/* The device discovery interval, default 60 seconds. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  pthread_t  discovery_thread  =  AST_PTHREADT_NULL ; 	/* The discovery thread */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  sdp_session_t  * sdp_session ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MUTEX_DEFINE_STATIC ( unload_mutex ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  unloading_flag  =  0 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  check_unloading ( void ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  void  set_unloading ( void ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  mbl_type  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MBL_TYPE_PHONE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MBL_TYPE_HEADSET 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  adapter_pvt  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  dev_id ; 					/* device id */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  hci_socket ; 					/* device descriptor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  id [ 31 ] ; 					/* the 'name' from mobile.conf */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bdaddr_t  addr ; 					/* adddress of adapter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  inuse : 1 ; 				/* are we in use ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  alignment_detection : 1 ; 		/* do alignment detection on this adapter? */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  io_context  * io ; 				/*!< io context for audio connections */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  io_context  * accept_io ; 			/*!< io context for sco listener */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  * sco_id ; 					/*!< the io context id of the sco listener socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  sco_socket ; 					/*!< sco listener socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  sco_listener_thread ; 			/*!< sco listener thread */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( adapter_pvt )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  AST_RWLIST_HEAD_STATIC ( adapters ,  adapter_pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  msg_queue_entry ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  hfp_pvt ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  mbl_pvt  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * owner ; 			/* Channel we belong to, possibly NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  fr ; 				/* "null" frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_t  lock ; 				/*!< pvt lock */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! queue for messages we are expecting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_HEAD_NOLOCK ( msg_queue ,  msg_queue_entry )  msg_queue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									enum  mbl_type  type ; 				/* Phone or Headset */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  id [ 31 ] ; 					/* The id from mobile.conf */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  group ; 					/* group number for group dialling */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bdaddr_t  addr ; 					/* address of device */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 			/* the adapter we use */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  context [ AST_MAX_CONTEXT ] ; 			/* the context for incoming calls */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hfp_pvt  * hfp ; 				/*!< hfp pvt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rfcomm_port ; 				/* rfcomm port number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rfcomm_socket ; 				/* rfcomm socket descriptor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  rfcomm_buf [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  io_buf [ CHANNEL_FRAME_SIZE  +  AST_FRIENDLY_OFFSET ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_smoother  * bt_out_smoother ; 			/* our bt_out_smoother, for making 48 byte frames */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_smoother  * bt_in_smoother ; 			/* our smoother, for making "normal" CHANNEL_FRAME_SIZEed byte frames */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  sco_socket ; 					/* sco socket descriptor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  monitor_thread ; 			/* monitor thread handle */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  timeout ; 					/*!< used to set the timeout for rfcomm data (may be used in the future) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  no_callsetup : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  has_sms : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  do_alignment_detection : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  alignment_detection_triggered : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  blackberry : 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									short  alignment_samples [ 4 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  alignment_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ring_sched_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_dsp  * dsp ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-20 17:49:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_sched_context  * sched ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  hangupcause ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* flags */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  outgoing : 1 ; 	/*!< outgoing call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  incoming : 1 ; 	/*!< incoming call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  outgoing_sms : 1 ; 	/*!< outgoing sms */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  incoming_sms : 1 ; 	/*!< outgoing sms */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  needcallerid : 1 ; 	/*!< we need callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  needchup : 1 ; 	/*!< we need to send a chup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  needring : 1 ; 	/*!< we need to send a RING */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  answered : 1 ; 	/*!< we sent/received an answer */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									unsigned  int  connected : 1 ; 	/*!< do we have an rfcomm connection to a device */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( mbl_pvt )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! Structure used by hfp_parse_clip to return two items */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  cidinfo  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cnum ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cnam ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  AST_RWLIST_HEAD_STATIC ( devices ,  mbl_pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ok ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_error ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ciev ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_clip ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ring ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cmti ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cmgr ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  handle_response_cusd ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  handle_response_busy ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_no_dialtone ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_no_carrier ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  handle_sms_prompt ( struct  mbl_pvt  * pvt ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLI stuff */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_show_devices ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_search ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_rfcomm ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) ;  
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_cusd ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_cli_entry  mbl_cli [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_mobile_show_devices ,  " Show Bluetooth Cell / Mobile devices " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_mobile_search ,        " Search for Bluetooth Cell / Mobile devices " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_mobile_rfcomm ,        " Send commands to the rfcomm port for debugging " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_mobile_cusd ,          " Send CUSD commands to the mobile " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* App stuff */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * app_mblstatus  =  " MobileStatus " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * mblstatus_synopsis  =  " MobileStatus(Device,Variable) " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * mblstatus_desc  =  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" MobileStatus(Device,Variable) \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"   Device - Id of mobile device from mobile.conf \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"   Variable - Variable to store status in will be 1-3. \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"              In order, Disconnected, Connected & Free, Connected & Busy. \n " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * app_mblsendsms  =  " MobileSendSMS " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * mblsendsms_synopsis  =  " MobileSendSMS(Device,Dest,Message) " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * mblsendsms_desc  =  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" MobileSendSms(Device,Dest,Message) \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"   Device - Id of device from mobile.conf \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"   Dest - destination \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"   Message - text of the message \n " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * mbl_new ( int  state ,  struct  mbl_pvt  * pvt ,  struct  cidinfo  * cidinfo ,  
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  ast_assigned_ids  * assignedids ,  const  struct  ast_channel  * requestor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 16:22:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * mbl_request ( const  char  * type ,  struct  ast_format_cap  * cap ,  
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  ast_assigned_ids  * assignedids ,  const  struct  ast_channel  * requestor ,  const  char  * data ,  int  * cause ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  mbl_call ( struct  ast_channel  * ast ,  const  char  * dest ,  int  timeout ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  mbl_hangup ( struct  ast_channel  * ast ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_answer ( struct  ast_channel  * ast ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_digit_end ( struct  ast_channel  * ast ,  char  digit ,  unsigned  int  duration ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * mbl_read ( struct  ast_channel  * ast ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_write ( struct  ast_channel  * ast ,  struct  ast_frame  * frame ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_fixup ( struct  ast_channel  * oldchan ,  struct  ast_channel  * newchan ) ;  
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  mbl_devicestate ( const  char  * data ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  do_alignment_detection ( struct  mbl_pvt  * pvt ,  char  * buf ,  int  buflen ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_queue_control ( struct  mbl_pvt  * pvt ,  enum  ast_control_frame_type  control ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_queue_hangup ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_ast_hangup ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  mbl_has_service ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_connect ( bdaddr_t  src ,  bdaddr_t  dst ,  int  remote_channel ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_write ( int  rsock ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_write_full ( int  rsock ,  char  * buf ,  size_t  count ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_wait ( int  rsock ,  int  * ms ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  ssize_t  rfcomm_read ( int  rsock ,  char  * buf ,  size_t  count ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_connect ( bdaddr_t  src ,  bdaddr_t  dst ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_write ( int  s ,  char  * buf ,  int  len ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_accept ( int  * id ,  int  fd ,  short  events ,  void  * data ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_bind ( struct  adapter_pvt  * adapter ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_sco_listen ( void  * data ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sdp_search ( char  * addr ,  int  profile ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  headset_send_ring ( const  void  * data ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bluetooth  handsfree  profile  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_ECNR	(1 << 0) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_CW	(1 << 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_CID	(1 << 2) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_VOICE	(1 << 3) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_VOLUME	(1 << 4) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_STATUS	(1 << 5) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_HF_CONTROL	(1 << 6) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_CW	(1 << 0) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_ECNR	(1 << 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_VOICE	(1 << 2) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_RING	(1 << 3) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_TAG	(1 << 4) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_REJECT	(1 << 5) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_STATUS	(1 << 6) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_CONTROL	(1 << 7) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_AG_ERRORS	(1 << 8) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_UNKNOWN	-1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_NONE		0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_SERVICE	1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALL		2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLSETUP	3 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLHELD	4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_SIGNAL		5 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_ROAM		6 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_BATTCHG	7 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* call indicator values */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALL_NONE	0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALL_ACTIVE	1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* callsetup indicator values */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLSETUP_NONE		0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLSETUP_INCOMING	1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLSETUP_OUTGOING	2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_CALLSETUP_ALERTING	3 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* service indicator values */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_SERVICE_NONE		0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define HFP_CIND_SERVICE_AVAILABLE	1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  This  struct  holds  HFP  features  that  we  support . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  hfp_hf  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ecnr : 1 ; 	/*!< echo-cancel/noise reduction */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cw : 1 ; 	/*!< call waiting and three way calling */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cid : 1 ; 	/*!< cli presentation (callier id) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  voice : 1 ; 	/*!< voice recognition activation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  volume : 1 ; 	/*!< remote volume control */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  status : 1 ; 	/*!< enhanced call status */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  control : 1 ; 	/*!< enhanced call control*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  This  struct  holds  HFP  features  the  AG  supports . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  hfp_ag  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cw : 1 ; 	/*!< three way calling */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ecnr : 1 ; 	/*!< echo-cancel/noise reduction */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  voice : 1 ; 	/*!< voice recognition */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ring : 1 ; 	/*!< in band ring tone capability */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  tag : 1 ; 	/*!< attach a number to a voice tag */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  reject : 1 ; 	/*!< ability to reject a call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  status : 1 ; 	/*!< enhanced call status */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  control : 1 ; 	/*!< enhanced call control*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  errors : 1 ; 	/*!< extended error result codes*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  This  struct  holds  mappings  for  indications . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  hfp_cind  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  service ; 	/*!< whether we have service or not */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  call ; 	/*!< call state */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  callsetup ; 	/*!< bluetooth call setup indications */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  callheld ; 	/*!< bluetooth call hold indications */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  signal ; 	/*!< signal strength */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  roam ; 	/*!< roaming indicator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  battchg ; 	/*!< battery charge indicator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  This  struct  holds  state  information  about  the  current  hfp  connection . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  hfp_pvt  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * owner ; 		/*!< the mbl_pvt struct that owns this struct */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  initialized : 1 ; 		/*!< whether a service level connection exists or not */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  nocallsetup : 1 ; 		/*!< whether we detected a callsetup indicator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hfp_ag  brsf ; 		/*!< the supported feature set of the AG */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cind_index [ 16 ] ; 		/*!< the cind/ciev index to name mapping for this AG */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cind_state [ 16 ] ; 		/*!< the cind/ciev state for this AG */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hfp_cind  cind_map ; 	/*!< the cind name to index mapping for this AG */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rsock ; 			/*!< our rfcomm socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rport ; 			/*!< our rfcomm port */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  sent_alerting ; 		/*!< have we sent alerting? */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Our supported features.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  we  only  support  caller  id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  hfp_hf  hfp_our_brsf  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. ecnr  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. cw  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. cid  =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. voice  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. volume  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. status  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. control  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_ciev ( struct  hfp_pvt  * hfp ,  char  * buf ,  int  * value ) ;  
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  cidinfo  hfp_parse_clip ( struct  hfp_pvt  * hfp ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  parse_next_token ( char  string [ ] ,  const  int  start ,  const  char  delim ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cmti ( struct  hfp_pvt  * hfp ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cmgr ( struct  hfp_pvt  * hfp ,  char  * buf ,  char  * * from_number ,  char  * * text ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_brsf ( struct  hfp_pvt  * hfp ,  const  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cind ( struct  hfp_pvt  * hfp ,  char  * buf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cind_test ( struct  hfp_pvt  * hfp ,  char  * buf ) ;  
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * hfp_parse_cusd ( struct  hfp_pvt  * hfp ,  char  * buf ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_brsf2int ( struct  hfp_hf  * hf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  hfp_ag  * hfp_int2brsf ( int  brsf ,  struct  hfp_ag  * ag ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_brsf ( struct  hfp_pvt  * hfp ,  struct  hfp_hf  * brsf ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cind ( struct  hfp_pvt  * hfp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cind_test ( struct  hfp_pvt  * hfp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmer ( struct  hfp_pvt  * hfp ,  int  status ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_clip ( struct  hfp_pvt  * hfp ,  int  status ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_vgs ( struct  hfp_pvt  * hfp ,  int  value ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#if 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_vgm ( struct  hfp_pvt  * hfp ,  int  value ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_dtmf ( struct  hfp_pvt  * hfp ,  char  digit ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgf ( struct  hfp_pvt  * hfp ,  int  mode ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cnmi ( struct  hfp_pvt  * hfp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgr ( struct  hfp_pvt  * hfp ,  int  index ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgs ( struct  hfp_pvt  * hfp ,  const  char  * number ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_sms_text ( struct  hfp_pvt  * hfp ,  const  char  * message ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_chup ( struct  hfp_pvt  * hfp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_atd ( struct  hfp_pvt  * hfp ,  const  char  * number ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_ata ( struct  hfp_pvt  * hfp ) ;  
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  hfp_send_cusd ( struct  hfp_pvt  * hfp ,  const  char  * code ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bluetooth  headset  profile  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_ok ( int  rsock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_error ( int  rsock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_vgs ( int  rsock ,  int  gain ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_vgm ( int  rsock ,  int  gain ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_ring ( int  rsock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Hayes  AT  command  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  enum  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* errors */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_PARSE_ERROR  =  - 2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_READ_ERROR  =  - 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_UNKNOWN  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* at responses */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_OK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_ERROR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_RING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_BRSF , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CIND , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CIEV , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CLIP , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMTI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMGR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_SMS_PROMPT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMS_ERROR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* at commands */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_A , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_D , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CHUP , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CKPD , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMGS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_VGM , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_VGS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_VTS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMGF , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CNMI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CMER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_CIND_TEST , 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AT_CUSD , 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AT_BUSY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_NO_DIALTONE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_NO_CARRIER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AT_ECAM , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  at_message_t ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  at_match_prefix ( char  * buf ,  char  * prefix ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  at_message_t  at_read_full ( int  rsock ,  char  * buf ,  size_t  count ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * at_msg2str ( at_message_t  msg ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  msg_queue_entry  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									at_message_t  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									at_message_t  response_to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									void  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( msg_queue_entry )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  msg_queue_push ( struct  mbl_pvt  * pvt ,  at_message_t  expect ,  at_message_t  response_to ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  msg_queue_push_data ( struct  mbl_pvt  * pvt ,  at_message_t  expect ,  at_message_t  response_to ,  void  * data ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  msg_queue_entry  * msg_queue_pop ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  msg_queue_free_and_pop ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  msg_queue_flush ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  msg_queue_entry  * msg_queue_head ( struct  mbl_pvt  * pvt ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  channel  stuff 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 16:22:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel_tech  mbl_tech  =  {  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. type  =  " Mobile " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. description  =  " Bluetooth Mobile Device Channel Driver " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. requester  =  mbl_request , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. call  =  mbl_call , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. hangup  =  mbl_hangup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. answer  =  mbl_answer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. send_digit_end  =  mbl_digit_end , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. read  =  mbl_read , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. write  =  mbl_write , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. fixup  =  mbl_fixup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. devicestate  =  mbl_devicestate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLI Commands implementation */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_show_devices ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  bdaddr [ 18 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  group [ 6 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define FORMAT1 "%-15.15s %-17.17s %-5.5s %-15.15s %-9.9s %-10.10s %-3.3s\n" 
  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " mobile show devices " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: mobile show devices \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Shows the state of Bluetooth Cell / Mobile devices. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  FORMAT1 ,  " ID " ,  " Address " ,  " Group " ,  " Adapter " ,  " Connected " ,  " State " ,  " SMS " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ba2str ( & pvt - > addr ,  bdaddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( group ,  sizeof ( group ) ,  " %d " ,  pvt - > group ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  FORMAT1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bdaddr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > adapter - > id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > connected  ?  " Yes "  :  " No " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												( ! pvt - > connected )  ?  " None "  :  ( pvt - > owner )  ?  " Busy "  :  ( pvt - > outgoing_sms  | |  pvt - > incoming_sms )  ?  " SMS "  :  ( mbl_has_service ( pvt ) )  ?  " Free "  :  " No Service " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												( pvt - > has_sms )  ?  " Yes "  :  " No " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef FORMAT1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_search ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inquiry_info  * ii  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  max_rsp ,  num_rsp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  len ,  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  phport ,  hsport ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  addr [ 19 ]  =  { 0 } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  name [ 31 ]  =  { 0 } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FORMAT1 "%-17.17s %-30.30s %-6.6s %-7.7s %-4.4s\n" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FORMAT2 "%-17.17s %-30.30s %-6.6s %-7.7s %d\n" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " mobile search " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: mobile search \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Searches for Bluetooth Cell / Mobile devices in range. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* find a free adapter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & adapters ,  adapter ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! adapter - > inuse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! adapter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " All Bluetooth adapters are in use at this time. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len   =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									max_rsp  =  255 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									flags  =  IREQ_CACHE_FLUSH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-31 20:21:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ii  =  ast_alloca ( max_rsp  *  sizeof ( inquiry_info ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									num_rsp  =  hci_inquiry ( adapter - > dev_id ,  len ,  max_rsp ,  NULL ,  & ii ,  flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( num_rsp  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  FORMAT1 ,  " Address " ,  " Name " ,  " Usable " ,  " Type " ,  " Port " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  num_rsp ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ba2str ( & ( ii  +  i ) - > bdaddr ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											name [ 0 ]  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hci_read_remote_name ( adapter - > hci_socket ,  & ( ii  +  i ) - > bdaddr ,  sizeof ( name )  -  1 ,  name ,  0 )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												strcpy ( name ,  " [unknown] " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											phport  =  sdp_search ( addr ,  HANDSFREE_AGW_PROFILE_ID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! phport ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hsport  =  sdp_search ( addr ,  HEADSET_PROFILE_ID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hsport  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  FORMAT2 ,  addr ,  name ,  ( phport  >  0  | |  hsport  >  0 )  ?  " Yes "  :  " No " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												( phport  >  0 )  ?  " Phone "  :  " Headset " ,  ( phport  >  0 )  ?  phport  :  hsport ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " No Bluetooth Cell / Mobile devices found. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef FORMAT1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef FORMAT2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_rfcomm ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  buf [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " mobile rfcomm " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: mobile rfcomm <device ID> <command> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Send <command> to the rfcomm port on the device \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        with the specified <device ID>. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( pvt - > id ,  a - > argv [ 2 ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Device %s not found. \n " ,  a - > argv [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > connected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Device %s not connected. \n " ,  a - > argv [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_unlock_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( buf ,  sizeof ( buf ) ,  " %s \r " ,  a - > argv [ 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_write ( pvt - > rfcomm_socket ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_push ( pvt ,  AT_OK ,  AT_UNKNOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_unlock_pvt :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * handle_cli_mobile_cusd ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  buf [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " mobile cusd " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: mobile cusd <device ID> <command> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Send cusd <command> to the rfcomm port on the device \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        with the specified <device ID>. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( pvt - > id ,  a - > argv [ 2 ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Device %s not found. \n " ,  a - > argv [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > connected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Device %s not connected. \n " ,  a - > argv [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_unlock_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( buf ,  sizeof ( buf ) ,  " %s " ,  a - > argv [ 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hfp_send_cusd ( pvt - > hfp ,  buf )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CUSD ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " [%s] error sending CUSD \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_unlock_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_unlock_pvt :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Dialplan  applications  implementation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_status_exec ( struct  ast_channel  * ast ,  const  char  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * parse ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  stat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  status [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( variable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parse  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( args ,  parse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( args . device )  | |  ast_strlen_zero ( args . variable ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stat  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( pvt - > id ,  args . device ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > connected ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											stat  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > owner ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											stat  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( status ,  sizeof ( status ) ,  " %d " ,  stat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( ast ,  args . variable ,  status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_sendsms_exec ( struct  ast_channel  * ast ,  const  char  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * parse ,  * message ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( dest ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parse  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( args ,  parse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( args . device ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " NULL device for message -- SMS will not be sent. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( args . dest ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " NULL destination for message -- SMS will not be sent. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( args . message ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " NULL Message to be sent -- SMS will not be sent. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( pvt - > id ,  args . device ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Bluetooth device %s wasn't found in the list -- SMS will not be sent. \n " ,  args . device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > connected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Bluetooth device %s wasn't connected -- SMS will not be sent. \n " ,  args . device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_unlock_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > has_sms )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Bluetooth device %s doesn't handle SMS -- SMS will not be sent. \n " ,  args . device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_unlock_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									message  =  ast_strdup ( args . message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hfp_send_cmgs ( pvt - > hfp ,  args . dest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										| |  msg_queue_push_data ( pvt ,  AT_SMS_PROMPT ,  AT_CMGS ,  message ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " [%s] problem sending SMS message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_free_message ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_free_message :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_unlock_pvt :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Channel  Driver  callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * mbl_new ( int  state ,  struct  mbl_pvt  * pvt ,  struct  cidinfo  * cidinfo ,  
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  ast_assigned_ids  * assignedids ,  const  struct  ast_channel  * requestor ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > answered  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > alignment_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > alignment_detection_triggered  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > adapter - > alignment_detection ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > do_alignment_detection  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > do_alignment_detection  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_smoother_reset ( pvt - > bt_out_smoother ,  DEVICE_FRAME_SIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_smoother_reset ( pvt - > bt_in_smoother ,  CHANNEL_FRAME_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_dsp_digitreset ( pvt - > dsp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									chn  =  ast_channel_alloc ( 1 ,  state , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cidinfo  ?  cidinfo - > cnum  :  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cidinfo  ?  cidinfo - > cnam  :  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  0 ,  pvt - > context ,  assignedids ,  requestor ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Mobile/%s-%04lx " ,  pvt - > id ,  ast_random ( )  &  0xffff ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ! chn )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_tech_set ( chn ,  & mbl_tech ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_nativeformats_set ( chn ,  mbl_tech . capabilities ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_set_rawreadformat ( chn ,  DEVICE_FRAME_FORMAT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_set_rawwriteformat ( chn ,  DEVICE_FRAME_FORMAT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_set_writeformat ( chn ,  DEVICE_FRAME_FORMAT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_set_readformat ( chn ,  DEVICE_FRAME_FORMAT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_tech_pvt_set ( chn ,  pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( state  = =  AST_STATE_RING ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_rings_set ( chn ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-24 20:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_language_set ( chn ,  " en " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									pvt - > owner  =  chn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > sco_socket  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_set_fd ( chn ,  0 ,  pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 19:28:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_unlock ( chn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  chn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 16:22:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * mbl_request ( const  char  * type ,  struct  ast_format_cap  * cap ,  
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  struct  ast_assigned_ids  * assignedids ,  const  struct  ast_channel  * requestor ,  const  char  * data ,  int  * cause ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chn  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * dest_dev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * dest_num  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-06 19:38:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  group  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Channel requested with no data \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cause  =  AST_CAUSE_INCOMPATIBLE_DESTINATION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_format_cap_iscompatible_format ( cap ,  DEVICE_FRAME_FORMAT )  = =  AST_FORMAT_CMP_NOT_EQUAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-09 10:01:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_str  * codec_buf  =  ast_str_alloca ( AST_FORMAT_CAP_NAMES_LEN ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Asked to get a channel of unsupported format '%s' \n " ,  ast_format_cap_get_names ( cap ,  & codec_buf ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										* cause  =  AST_CAUSE_FACILITY_NOT_IMPLEMENTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dest_dev  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dest_num  =  strchr ( dest_dev ,  ' / ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dest_num ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* dest_num + +  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ( dest_dev [ 0 ]  = =  ' g ' )  | |  ( dest_dev [ 0 ]  = =  ' G ' ) )  & &  ( ( dest_dev [ 1 ]  > =  ' 0 ' )  & &  ( dest_dev [ 1 ]  < =  ' 9 ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										group  =  atoi ( & dest_dev [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Find requested device and make sure it's connected. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( group  >  - 1  & &  pvt - > group  = =  group  & &  pvt - > connected  & &  ! pvt - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! mbl_has_service ( pvt ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcmp ( pvt - > id ,  dest_dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt  | |  ! pvt - > connected  | |  pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Request to call on device %s which is not connected / already in use. \n " ,  dest_dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cause  =  AST_CAUSE_REQUESTED_CHAN_UNAVAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( pvt - > type  = =  MBL_TYPE_PHONE )  & &  ! dest_num )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Can't determine destination number. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cause  =  AST_CAUSE_INCOMPATIBLE_DESTINATION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									chn  =  mbl_new ( AST_STATE_DOWN ,  pvt ,  NULL ,  assignedids ,  requestor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! chn )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to allocate channel structure. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* cause  =  AST_CAUSE_REQUESTED_CHAN_UNAVAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  chn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  mbl_call ( struct  ast_channel  * ast ,  const  char  * dest ,  int  timeout )  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * dest_dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									char  * dest_num  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dest_dev  =  ast_strdupa ( dest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_PHONE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dest_num  =  strchr ( dest_dev ,  ' / ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! dest_num )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Cant determine destination number. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* dest_num + +  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ast_channel_state ( ast )  ! =  AST_STATE_DOWN )  & &  ( ast_channel_state ( ast )  ! =  AST_STATE_RESERVED ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " mbl_call called on %s, neither down nor reserved \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Calling %s on %s \n " ,  dest ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_PHONE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hfp_send_atd ( pvt - > hfp ,  dest_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " error sending ATD command on %s \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pvt - > hangupcause  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_push ( pvt ,  AT_OK ,  AT_D ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hsp_send_ring ( pvt - > rfcomm_socket ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " [%s] error ringing device \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( pvt - > ring_sched_id  =  ast_sched_add ( pvt - > sched ,  6000 ,  headset_send_ring ,  pvt ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " [%s] error ringing device \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > outgoing  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > needring  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_hangup ( struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_channel_tech_pvt ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Asked to hangup channel not connected \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " [%s] hanging up device \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_set_fd ( ast ,  0 ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > needchup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hfp_send_chup ( pvt - > hfp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_push ( pvt ,  AT_OK ,  AT_CHUP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > needchup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > outgoing  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > incoming  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > needring  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > owner  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_tech_pvt_set ( ast ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_setstate ( ast ,  AST_STATE_DOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_answer ( struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_HEADSET ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > incoming )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hfp_send_ata ( pvt - > hfp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_push ( pvt ,  AT_OK ,  AT_A ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > answered  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_digit_end ( struct  ast_channel  * ast ,  char  digit ,  unsigned  int  duration )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_HEADSET ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hfp_send_dtmf ( pvt - > hfp ,  digit ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error sending digit %c \n " ,  pvt - > id ,  digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_push ( pvt ,  AT_OK ,  AT_VTS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " [%s] dialed %c \n " ,  pvt - > id ,  digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * mbl_read ( struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * fr  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " *** mbl_read() \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ast_mutex_trylock ( & pvt - > lock ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CHANNEL_DEADLOCK_AVOIDANCE ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > owner  | |  pvt - > sco_socket  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & pvt - > fr ,  0x00 ,  sizeof ( struct  ast_frame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . frametype  =  AST_FRAME_VOICE ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pvt - > fr . subclass . format  =  DEVICE_FRAME_FORMAT ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									pvt - > fr . src  =  " Mobile " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . offset  =  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . delivery . tv_sec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . delivery . tv_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > fr . data . ptr  =  pvt - > io_buf  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( r  =  read ( pvt - > sco_socket ,  pvt - > fr . data . ptr ,  DEVICE_FRAME_SIZE ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( errno  ! =  EAGAIN  & &  errno  ! =  EINTR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] read error %d, going to wait for new connection \n " ,  pvt - > id ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_set_fd ( ast ,  0 ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pvt - > fr . datalen  =  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > fr . samples  =  r  /  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( pvt - > do_alignment_detection ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											do_alignment_detection ( pvt ,  pvt - > fr . data . ptr ,  r ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_smoother_feed ( pvt - > bt_in_smoother ,  & pvt - > fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fr  =  ast_smoother_read ( pvt - > bt_in_smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  while  ( fr  = =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fr  =  ast_dsp_process ( ast ,  pvt - > dsp ,  fr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_write ( struct  ast_channel  * ast ,  struct  ast_frame  * frame )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ast_channel_tech_pvt ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " *** mbl_write \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frame - > frametype  ! =  AST_FRAME_VOICE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ast_mutex_trylock ( & pvt - > lock ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CHANNEL_DEADLOCK_AVOIDANCE ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_smoother_feed ( pvt - > bt_out_smoother ,  frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ( f  =  ast_smoother_read ( pvt - > bt_out_smoother ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										sco_write ( pvt - > sco_socket ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_fixup ( struct  ast_channel  * oldchan ,  struct  ast_channel  * newchan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ast_channel_tech_pvt ( newchan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-09 21:32:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " fixup failed, no pvt on newchan \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > owner  = =  oldchan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > owner  =  newchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  mbl_devicestate ( const  char  * data )  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * device ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  AST_DEVICE_INVALID ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									device  =  ast_strdupa ( S_OR ( data ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Checking device state for device %s \n " ,  device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( pvt - > id ,  device ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > connected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > owner ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_DEVICE_INUSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_DEVICE_NOT_INUSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! mbl_has_service ( pvt ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_DEVICE_UNAVAILABLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Callback  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do_alignment_detection ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									This  routine  attempts  to  detect  where  we  get  misaligned  sco  audio  data  from  the  bluetooth  adaptor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Its  enabled  by  alignmentdetect = yes  under  the  adapter  entry  in  mobile . conf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Some  adapters  suffer  a  problem  where  occasionally  they  will  byte  shift  the  audio  stream  one  byte  to  the  right . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									The  result  is  static  or  white  noise  on  the  inbound  ( from  the  adapter )  leg  of  the  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									This  is  characterised  by  a  sudden  jump  in  magnitude  of  the  value  of  the  16  bit  samples . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Here  we  look  at  the  first  4  48  byte  frames .  We  average  the  absolute  values  of  each  sample  in  the  frame , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									then  average  the  sum  of  the  averages  of  frames  1 ,  2 ,  and  3. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Frame  zero  is  usually  zero . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									If  the  end  result  >  100 ,  and  it  usually  is  if  we  have  the  problem ,  set  a  flag  and  compensate  by  shifting  the  bytes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  each  subsequent  frame  during  the  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 15:57:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									If  the  result  is  < =  100  then  clear  the  flag  so  we  don ' t  come  back  in  here . . . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									This  seems  to  work  OK . . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  do_alignment_detection ( struct  mbl_pvt  * pvt ,  char  * buf ,  int  buflen )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									short  a ,  * s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > alignment_detection_triggered )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i = buflen ,  p = buf + buflen - 1 ;  i > 0 ;  i - - ,  p - - ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* p  =  * ( p - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* ( p + 1 )  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > alignment_count  <  4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  ( short  * ) buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i = 0 ,  a = 0 ;  i < buflen / 2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											a  + =  * s + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											a  / =  i + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > alignment_samples [ pvt - > alignment_count + + ]  =  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Alignment Detection result is [%-d %-d %-d %-d] \n " ,  pvt - > alignment_samples [ 0 ] ,  pvt - > alignment_samples [ 1 ] ,  pvt - > alignment_samples [ 2 ] ,  pvt - > alignment_samples [ 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  =  abs ( pvt - > alignment_samples [ 1 ] )  +  abs ( pvt - > alignment_samples [ 2 ] )  +  abs ( pvt - > alignment_samples [ 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  / =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a  >  100 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > alignment_detection_triggered  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Alignment Detection Triggered. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > do_alignment_detection  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_queue_control ( struct  mbl_pvt  * pvt ,  enum  ast_control_frame_type  control )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_channel_trylock ( pvt - > owner ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DEADLOCK_AVOIDANCE ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_queue_control ( pvt - > owner ,  control ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( pvt - > owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_queue_hangup ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_channel_trylock ( pvt - > owner ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DEADLOCK_AVOIDANCE ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( pvt - > hangupcause  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_hangupcause_set ( pvt - > owner ,  pvt - > hangupcause ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_queue_hangup ( pvt - > owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( pvt - > owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_ast_hangup ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2013-07-17 22:30:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_hangup ( pvt - > owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-29 21:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Check  if  a  mobile  device  has  service . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  1  this  device  has  service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  no  service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  This  function  will  always  indicate  that  service  is  available  if  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  given  device  does  not  support  service  indication . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_has_service ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  ! =  MBL_TYPE_PHONE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > hfp - > cind_map . service ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > hfp - > cind_state [ pvt - > hfp - > cind_map . service ]  = =  HFP_CIND_SERVICE_AVAILABLE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_connect ( bdaddr_t  src ,  bdaddr_t  dst ,  int  remote_channel )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_rc  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( s  =  socket ( PF_BLUETOOTH ,  SOCK_STREAM ,  BTPROTO_RFCOMM ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " socket() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & addr ,  0 ,  sizeof ( addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . rc_family  =  AF_BLUETOOTH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bacpy ( & addr . rc_bdaddr ,  & src ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-17 02:32:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									addr . rc_channel  =  ( uint8_t )  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( bind ( s ,  ( struct  sockaddr  * ) & addr ,  sizeof ( addr ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " bind() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & addr ,  0 ,  sizeof ( addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . rc_family  =  AF_BLUETOOTH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bacpy ( & addr . rc_bdaddr ,  & dst ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . rc_channel  =  remote_channel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( connect ( s ,  ( struct  sockaddr  * ) & addr ,  sizeof ( addr ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " connect() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Write  to  an  rfcomm  socket . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  socket  to  write  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  null  terminated  buffer  to  write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  will  write  characters  from  buf .   The  buffer  must  be  null 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  terminated . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_write ( int  rsock ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write_full ( rsock ,  buf ,  strlen ( buf ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Write  to  an  rfcomm  socket . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  socket  to  write  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  count  the  number  of  characters  from  the  buffer  to  write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  will  write  count  characters  from  buf .   It  will  always  write 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  count  chars  unless  it  encounters  an  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_write_full ( int  rsock ,  char  * buf ,  size_t  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * p  =  buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ssize_t  out_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " rfcomm_write() (%d) [%.*s] \n " ,  rsock ,  ( int )  count ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( count  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( out_count  =  write ( rsock ,  p ,  count ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " rfcomm_write() error [%d] \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										count  - =  out_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p  + =  out_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Wait  for  activity  on  an  rfcomm  socket . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  socket  to  watch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  ms  a  pointer  to  an  int  containing  a  timeout  in  ms 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  zero  on  timeout  and  the  socket  fd  ( non - zero )  otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  timeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_wait ( int  rsock ,  int  * ms )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  exception ,  outfd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outfd  =  ast_waitfor_n_fd ( & rsock ,  1 ,  ms ,  & exception ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( outfd  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										outfd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  outfd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef RFCOMM_READ_DEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define rfcomm_read_debug(c) __rfcomm_read_debug(c) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  __rfcomm_read_debug ( char  c )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( c  = =  ' \r ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " rfcomm_read:  \\ r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( c  = =  ' \n ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " rfcomm_read:  \\ n \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " rfcomm_read: %c \n " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define rfcomm_read_debug(c) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Append  the  given  character  to  the  given  buffer  and  increase  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  in_count . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  inline  rfcomm_append_buf ( char  * * buf ,  size_t  count ,  size_t  * in_count ,  char  c )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( * in_count  <  count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( * in_count ) + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* ( * buf ) + +  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  a  character  from  the  given  stream  and  check  if  it  matches  what 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  we  expected . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_and_expect_char ( int  rsock ,  char  * result ,  char  expected )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! result ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										result  =  & c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  read ( rsock ,  result ,  1 ) )  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_read_debug ( * result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( * result  ! =  expected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  a  character  from  the  given  stream  and  append  it  to  the  given 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  buffer  if  it  matches  the  expected  character . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_and_append_char ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count ,  char  * result ,  char  expected )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! result ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										result  =  & c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  result ,  expected ) )  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_append_buf ( buf ,  count ,  in_count ,  * result ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Read  until  \ verbatim  ' \ r \ n ' .  \ endverbatim 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  consumes  the  \ verbatim ' \ r \ n ' \ endverbatim  but  does  not  add  it  to  buf . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_until_crlf ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( res  =  read ( rsock ,  & c ,  1 ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_read_debug ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( c  = =  ' \r ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \n ' ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( res  = =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  the  remainder  of  an  AT  SMS  prompt . 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  the  entire  parsed  string  is  \ verbatim  ' \ r \ n >  '  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  By  the  time  this  function  is  executed ,  only  a  '   '  is  left  to  read . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_sms_prompt ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_and_append_char ( rsock ,  buf ,  count ,  in_count ,  NULL ,  '   ' ) )  <  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_log ( LOG_ERROR ,  " error parsing SMS prompt on rfcomm socket \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Read  until  a  \ verbatim  \ r \ nOK \ r \ n  \ endverbatim  message . 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_until_ok ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* here, we read until finding a \r\n, then we read one character at a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  time  looking  for  the  string  ' \ r \ nOK \ r \ n ' .   If  we  only  find  a  partial 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  match ,  we  place  that  in  the  buffer  and  try  again .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_until_crlf ( rsock ,  buf ,  count ,  in_count ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \r ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \n ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' O ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' K ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' O ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \r ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' O ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' K ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \n ' ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' O ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' K ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* we have successfully parsed a '\r\nOK\r\n' string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  the  remainder  of  a  + CMGR  message . 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  the  entire  parsed  string  is  \ verbatim  ' + CMGR :  . . . \ r \ n . . . \ r \ n . . . \ r \ n . . . \ r \ nOK \ r \ n '  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_cmgr ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* append the \r\n that was stripped by the calling function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \r ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_append_buf ( buf ,  count ,  in_count ,  ' \n ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_until_ok ( rsock ,  buf ,  count ,  in_count ) )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " error reading +CMGR message on rfcomm socket \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  and  AT  result  code . 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  the  entire  parsed  string  is  \ verbatim  ' \ r \ n < result  code > \ r \ n '  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_result ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \n ' ) )  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_and_append_char ( rsock ,  buf ,  count ,  in_count ,  & c ,  ' > ' ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rfcomm_read_sms_prompt ( rsock ,  buf ,  count ,  in_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( res  ! =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  rfcomm_read_until_crlf ( rsock ,  buf ,  count ,  in_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  ! =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* check for CMGR, which contains an embedded \r\n pairs terminated by
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  an  \ r \ nOK \ r \ n  message  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( * in_count  > =  5  & &  ! strncmp ( * buf  -  * in_count ,  " +CMGR " ,  5 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  rfcomm_read_cmgr ( rsock ,  buf ,  count ,  in_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
									
										
										
										
											2012-04-06 18:19:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_log ( LOG_ERROR ,  " error parsing AT result on rfcomm socket \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  the  remainder  of  an  AT  command . 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  the  entire  parsed  string  is  \ verbatim  ' < at  command > \ r '  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rfcomm_read_command ( int  rsock ,  char  * * buf ,  size_t  count ,  size_t  * in_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( res  =  read ( rsock ,  & c ,  1 ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_read_debug ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* stop when we get to '\r' */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( c  = =  ' \r ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_append_buf ( buf ,  count ,  in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  one  Hayes  AT  message  from  an  rfcomm  socket . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  read  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  store  the  result  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  count  the  size  of  the  buffer  or  the  maximum  number  of  characters  to  read 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Here  we  need  to  read  complete  Hayes  AT  messages .   The  AT  message  formats  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  support  are  listed  below . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ verbatim 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ r \ n < result  code > \ r \ n 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  < at  command > \ r 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ r \ n > 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ endverbatim 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  These  formats  correspond  to  AT  result  codes ,  AT  commands ,  and  the  AT  SMS 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  prompt  respectively .   When  messages  are  read  the  leading  and  trailing  \ verbatim  ' \r '  \ endverbatim 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  and  \ verbatim  ' \n '  \ endverbatim  characters  are  discarded .   If  the  given  buffer  is  not  large  enough 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  to  hold  the  response ,  what  does  not  fit  in  the  buffer  will  be  dropped . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  The  rfcomm  connection  to  the  device  is  asynchronous ,  so  there  is  no 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  guarantee  that  responses  will  be  returned  in  a  single  read ( )  call .  We  handle 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  this  by  blocking  until  we  can  read  an  entire  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  end  of  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  read  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 2  parse  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  other  the  number  of  characters  added  to  buf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  ssize_t  rfcomm_read ( int  rsock ,  char  * buf ,  size_t  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ssize_t  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  in_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  rfcomm_read_and_expect_char ( rsock ,  & c ,  ' \r ' ) )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  rfcomm_read_result ( rsock ,  & buf ,  count ,  & in_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( res  = =  - 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rfcomm_append_buf ( & buf ,  count ,  & in_count ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  rfcomm_read_command ( rsock ,  & buf ,  count ,  & in_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  in_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sco  helpers  and  callbacks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_connect ( bdaddr_t  src ,  bdaddr_t  dst )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_sco  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( s  =  socket ( PF_BLUETOOTH ,  SOCK_SEQPACKET ,  BTPROTO_SCO ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " socket() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* XXX this does not work with the do_sco_listen() thread (which also bind()s
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  this  address ) .   Also  I  am  not  sure  if  it  is  necessary .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#if 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & addr ,  0 ,  sizeof ( addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . sco_family  =  AF_BLUETOOTH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bacpy ( & addr . sco_bdaddr ,  & src ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bind ( s ,  ( struct  sockaddr  * ) & addr ,  sizeof ( addr ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " bind() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & addr ,  0 ,  sizeof ( addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . sco_family  =  AF_BLUETOOTH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bacpy ( & addr . sco_bdaddr ,  & dst ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( connect ( s ,  ( struct  sockaddr  * ) & addr ,  sizeof ( addr ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " sco connect() failed (%d). \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_write ( int  s ,  char  * buf ,  int  len )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( s  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 3 ,  " sco_write() not ready \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " sco_write() \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  =  write ( s ,  buf ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( r  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 3 ,  " sco write error %d \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Accept  SCO  connections . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  is  an  ast_io  callback  function  used  to  accept  incoming  sco 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  audio  connections . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_accept ( int  * id ,  int  fd ,  short  events ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter  =  ( struct  adapter_pvt  * )  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_sco  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									socklen_t  addrlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									socklen_t  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  saddr [ 18 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sco_options  so ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  sock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addrlen  =  sizeof ( struct  sockaddr_sco ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( sock  =  accept ( fd ,  ( struct  sockaddr  * ) & addr ,  & addrlen ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " error accepting audio connection on adapter %s \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  =  sizeof ( so ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									getsockopt ( sock ,  SOL_SCO ,  SCO_OPTIONS ,  & so ,  & len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ba2str ( & addr . sco_bdaddr ,  saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Incoming Audio Connection from device %s MTU is %d \n " ,  saddr ,  so . mtu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* figure out which device this sco connection belongs to */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! bacmp ( & pvt - > addr ,  & addr . sco_bdaddr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " could not find device for incoming audio connection \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > sco_socket  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > sco_socket  =  sock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_set_fd ( pvt - > owner ,  0 ,  sock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " incoming audio connection for pvt without owner \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Bind  an  SCO  listener  socket  for  the  given  adapter . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  adapter  an  adapter_pvt 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  - 1  on  error ,  non  zero  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sco_bind ( struct  adapter_pvt  * adapter )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_sco  addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  opt  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( adapter - > sco_socket  =  socket ( PF_BLUETOOTH ,  SOCK_SEQPACKET ,  BTPROTO_SCO ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to create sco listener socket for adapter %s. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & addr ,  0 ,  sizeof ( addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr . sco_family  =  AF_BLUETOOTH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bacpy ( & addr . sco_bdaddr ,  & adapter - > addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( bind ( adapter - > sco_socket ,  ( struct  sockaddr  * ) & addr ,  sizeof ( addr ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to bind sco listener socket. (%d) \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_close_socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( setsockopt ( adapter - > sco_socket ,  SOL_SOCKET ,  SO_REUSEADDR ,  & opt ,  sizeof ( opt ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to setsockopt sco listener socket. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_close_socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( listen ( adapter - > sco_socket ,  5 )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to listen sco listener socket. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_close_socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  adapter - > sco_socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_close_socket :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( adapter - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									adapter - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Hayes  AT  command  helpers . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Match  the  given  buffer  with  the  given  prefix . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  match 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  prefix  the  prefix  to  match 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  at_match_prefix ( char  * buf ,  char  * prefix )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! strncmp ( buf ,  prefix ,  strlen ( prefix ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Read  an  AT  message  and  classify  it . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  an  rfcomm  socket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  store  the  result  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  count  the  size  of  the  buffer  or  the  maximum  number  of  characters  to  read 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  the  type  of  message  received ,  in  addition  buf  will  contain  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  message  received  and  will  be  null  terminated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ see  at_read ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  at_message_t  at_read_full ( int  rsock ,  char  * buf ,  size_t  count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ssize_t  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( s  =  rfcomm_read ( rsock ,  buf ,  count  -  1 ) )  <  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf [ s ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strcmp ( " OK " ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcmp ( " ERROR " ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcmp ( " RING " ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_RING ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcmp ( " AT+CKPD=200 " ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CKPD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcmp ( " >  " ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_SMS_PROMPT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CMTI: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CMTI ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CIEV: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CIEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +BRSF: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_BRSF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CIND: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CIND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CLIP: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CLIP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CMGR: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CMGR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +VGM: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_VGM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +VGS: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_VGS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CMS ERROR: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CMS_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " AT+VGM= " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_VGM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " AT+VGS= " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_VGS ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " +CUSD: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_CUSD ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " BUSY " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " NO DIALTONE " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_NO_DIALTONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " NO CARRIER " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_NO_CARRIER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( at_match_prefix ( buf ,  " *ECAV: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_ECAM ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AT_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Get  the  string  representation  of  the  given  AT  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  msg  the  message  to  process 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  a  string  describing  the  given  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  const  char  * at_msg2str ( at_message_t  msg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( msg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* errors */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_PARSE_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " PARSE ERROR " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_READ_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " READ ERROR " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " UNKNOWN " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* at responses */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_OK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " OK " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " ERROR " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " RING " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_BRSF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+BRSF " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CIND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CIND " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CIEV : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CIEV " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CLIP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CLIP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMTI : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CMTI " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMGR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CMGR " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_SMS_PROMPT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " SMS PROMPT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMS_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " +CMS ERROR " ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  AT_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " BUSY " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_NO_DIALTONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " NO DIALTONE " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_NO_CARRIER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " NO CARRIER " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* at commands */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_A : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " ATA " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_D : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " ATD " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CHUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CHUP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CKPD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CKPD " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CMGS " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_VGM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+VGM " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_VGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+VGS " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_VTS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+VTS " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMGF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CMGF " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CNMI : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CNMI " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CMER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CMER " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  AT_CIND_TEST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CIND=? " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  AT_CUSD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT+CUSD " ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  AT_ECAM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " AT*ECAM " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bluetooth  handsfree  profile  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 /*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  ECAV  event . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  - 1  on  error  ( parse  error )  or  a  ECAM  value  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 14:38:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Example : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ verbatim  * ECAV :  < ccid > , < ccstatus > , < calltype > [ , < processid > ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    [ , exitcause ] [ , < number > , < type > ]  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 14:38:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Example  indicating  busy : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ verbatim  * ECAV :  1 , 7 , 1  \ endverbatim 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_ecav ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ccid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ccstatus  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  calltype  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sscanf ( buf ,  " *ECAV: %2d,%2d,%2d " ,  & ccid ,  & ccstatus ,  & calltype ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error parsing ECAV event '%s' \n " ,  hfp - > owner - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ccstatus ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Enable  Sony  Ericsson  extensions  /  indications . 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_ecam ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " AT*ECAM=1 \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  CIEV  event . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  value  a  pointer  to  an  int  to  store  the  event  value  in  ( can  be  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  0  on  error  ( parse  error ,  or  unknown  event )  or  a  HFP_CIND_ *  value  on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_ciev ( struct  hfp_pvt  * hfp ,  char  * buf ,  int  * value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										value  =  & v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sscanf ( buf ,  " +CIEV: %d,%d " ,  & i ,  value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " [%s] error parsing CIEV event '%s' \n " ,  hfp - > owner - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  HFP_CIND_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Fix a variety of potential buffer overflows
* chan_mobile: Fixed an overrun where the cind_state buffer (an integer array
  of size 16) would be overrun due to improper bounds checking. At worst, the
  buffer can be overrun by a total of 48 bytes (assuming 4-byte integers),
  which would still leave it within the allocated memory of struct hfp.  This
  would corrupt other elements in that struct but not necessarily cause any
  further issues.
* app_sms: The array imsg is of size 250, while the array (ud) that the data
  is copied into is of size 160.  If the size of the inbound message is 
  greater then 160, up to 90 bytes could be overrun in ud.  This would corrupt
  the user data header (array udh) adjacent to ud.
* chan_unistim: A number of invalid memmoves are corrected.  These would move
  data (which may or may not be valid) into the ends of these buffers.
* asterisk: ast_console_toggle_loglevel does not check that the console log
  level being set is less then or equal to the allowed log levels of 32.
* format_pref: In ast_codec_pref_prepend, if any occurrence of the specified
  codec is not found, the value used to index into the array pref->order
  would be one greater then the maximum size of the array.
* jitterbuf: If the element being placed into the jitter buffer lands in the
  last available slot in the jitter history buffer, the insertion sort attempts
  to move the last entry in the buffer into one slot past the maximum length
  of the buffer.  Note that this occurred for both the min and max jitter
  history buffers.
* tdd: If a read from fsk_serial returns a character that is greater then 32,
  an attempt to read past one of the statically defined arrays containing the
  values that character maps to would occur.
* localtime: struct ast_time and tm are not the same size - ast_time is larger,
  although it contains the elements of tm within it in the same layout.  Hence,
  when using memcpy to copy the contents of tm into ast_time, the size of tm
  should be used, as opposed to the size of ast_time.
* extconf: this treats ast_timing's minmask array as if it had a length of 48,
  when it has defined the size of the array as 24.  pbx.h defines minmask as
  having a size of 48.
(issue ASTERISK-19668)
Reported by: Matt Jordan
........
Merged revisions 362485 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 362496 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@362497 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2012-04-19 02:40:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( i  > =  ARRAY_LEN ( hfp - > cind_state ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " [%s] CIEV event index too high (%s) \n " ,  hfp - > owner - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  HFP_CIND_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp - > cind_state [ i ]  =  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  hfp - > cind_index [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  CLIP  event . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  buf  will  be  modified  when  the  CID  string  is  parsed 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ return  a  cidinfo  structure  pointing  to  the  cnam  and  cnum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  data  in  buf .   On  parse  errors ,  either  or  both  pointers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  will  point  to  null  strings 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  cidinfo  hfp_parse_clip ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  tokens [ 6 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cnamtmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  delim  =  '   ' ; 	/* First token terminates with space */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  invalid  =  0 ; 	/* Number of invalid chars in cnam */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  cidinfo  cidinfo  =  {  NULL ,  NULL  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse clip info in the following format:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  + CLIP :  " 123456789 " , 128 , . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " [%s] hfp_parse_clip is processing  \" %s \" \n " ,  hfp - > owner - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tokens [ 0 ]  =  0 ; 		/* First token starts in position 0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  1 ;  i  <  ARRAY_LEN ( tokens ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tokens [ i ]  =  parse_next_token ( buf ,  tokens [ i  -  1 ] ,  delim ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delim  =  ' , ' ; 	/* Subsequent tokens terminate with comma */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " [%s] hfp_parse_clip found tokens: 0=%s, 1=%s, 2=%s, 3=%s, 4=%s, 5=%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hfp - > owner - > id ,  & buf [ tokens [ 0 ] ] ,  & buf [ tokens [ 1 ] ] ,  & buf [ tokens [ 2 ] ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										& buf [ tokens [ 3 ] ] ,  & buf [ tokens [ 4 ] ] ,  & buf [ tokens [ 5 ] ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Clean up cnum, and make sure it is legitimate since it is untrusted. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cidinfo . cnum  =  ast_strip_quoted ( & buf [ tokens [ 1 ] ] ,  " \" " ,  " \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_isphonenumber ( cidinfo . cnum ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] hfp_parse_clip invalid cidinfo.cnum data  \" %s \"  - deleting \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hfp - > owner - > id ,  cidinfo . cnum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cidinfo . cnum  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Some  docs  say  tokens  2  and  3  including  the  commas  are  optional . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  If  absent ,  that  would  move  CNAM  back  to  token  3. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cidinfo . cnam  =  & buf [ tokens [ 5 ] ] ; 	/* Assume it's in token 5 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( buf [ tokens [ 5 ] ]  = =  ' \0 '  & &  buf [ tokens [ 4 ] ]  = =  ' \0 ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Tokens 4 and 5 are empty.  See if token 3 looks like CNAM (starts with ") */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i  =  tokens [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( buf [ i ]  = =  '   ' )  { 		/* Find the first non-blank */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Starts with quote.  Use this for CNAM. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cidinfo . cnam  =  & buf [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Clean up CNAM. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cidinfo . cnam  =  ast_strip_quoted ( cidinfo . cnam ,  " \" " ,  " \" " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( cnamtmp  =  cidinfo . cnam ;  * cnamtmp  ! =  ' \0 ' ;  cnamtmp + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strchr ( " ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789-,abcdefghijklmnopqrstuvwxyz_ " ,  * cnamtmp ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* cnamtmp  =  ' _ ' ; 	/* Invalid.  Replace with underscore. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											invalid + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( invalid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " [%s] hfp_parse_clip replaced %d invalid byte(s) in cnam data \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hfp - > owner - > id ,  invalid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 2 ,  " [%s] hfp_parse_clip returns cnum=%s and cnam=%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hfp - > owner - > id ,  cidinfo . cnum ,  cidinfo . cnam ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cidinfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Terminate  current  token  and  return  an  index  to  start  of  the  next  token . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  string  the  null - terminated  string  being  parsed  ( will  be  altered ! ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  start  where  the  current  token  starts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  delim  the  token  termination  delimiter .   \ 0  is  also  considered  a  terminator . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  index  of  the  next  token .   May  be  the  same  as  this  token  if  the  string  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  exhausted . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  parse_next_token ( char  string [ ] ,  const  int  start ,  const  char  delim )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  quoting  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( index  =  start ;  string [ index ]  ! =  0 ;  index + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( string [ index ]  = =  delim )  & &  ! quoting  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Found the delimiter, outside of quotes.  This is the end of the token. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											string [ index ]  =  ' \0 ' ; 	/* Terminate this token. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											index + + ; 		/* Point the index to the start of the next token. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 			/* We're done. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( string [ index ]  = =  ' " '  & &  ! quoting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Found a beginning quote mark.  Remember it. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quoting  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( string [ index ]  = =  ' " '  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Found the end quote mark. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											quoting  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  index ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  CMTI  notification . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  buf  will  be  modified  when  the  CMTI  message  is  parsed 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ return  - 1  on  error  ( parse  error )  or  the  index  of  the  new  sms  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cmti ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  index  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse cmti info in the following format:
 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 *  + CMTI :  < mem > , < index > 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sscanf ( buf ,  " +CMTI: %*[^,],%d " ,  & index ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 2 ,  " [%s] error parsing CMTI event '%s' \n " ,  hfp - > owner - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  CMGR  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  from_number  a  pointer  to  a  char  pointer  which  will  store  the  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  text  a  pointer  to  a  char  pointer  which  will  store  the  message  text 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  buf  will  be  modified  when  the  CMGR  message  is  parsed 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  parse  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cmgr ( struct  hfp_pvt  * hfp ,  char  * buf ,  char  * * from_number ,  char  * * text )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse cmgr info in the following format:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  + CMGR :  < msg  status > , " +123456789 " , . . . \ r \ n 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  < message  text > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  strlen ( buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-18 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  s  & &  state  ! =  6 ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  0 :  /* search for start of the number section (,) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' , ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 :  /* find the opening quote (") */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-16 04:14:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  2 :  /* mark the start of the number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( from_number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												* from_number  =  & buf [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  3 :  /* search for the end of the number (") */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf [ i ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  4 :  /* search for the start of the message text (\n) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' \n ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  5 :  /* mark the start of the message text */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( text )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												* text  =  & buf [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( state  ! =  6 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  a  CUSD  answer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-22 20:43:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  buf  will  be  modified  when  the  CUSD  string  is  parsed 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ return  NULL  on  error  ( parse  error )  or  a  pointer  to  the  cusd  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  information  in  buf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * hfp_parse_cusd ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-01-14 15:51:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  message_start ,  message_end ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * cusd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse cusd message in the following format:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  + CUSD :  0 , " 100,00 EURO, valid till 01.01.2010, you are using tariff  " Mega  Tariff " . More informations *111#. " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									message_start  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									message_end  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  strlen ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Find the start of the message (") */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  s ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											message_start  =  i  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( message_start  = =  0  | |  message_start  > =  s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Find the end of the message (") */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  s ;  i  >  0 ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											message_end  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( message_end  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( message_start  > =  message_end )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cusd  =  & buf [ message_start ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf [ message_end ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cusd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Convert  a  hfp_hf  struct  to  a  BRSF  int . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hf  an  hfp_hf  brsf  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  an  integer  representing  the  given  brsf  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_brsf2int ( struct  hfp_hf  * hf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  brsf  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > ecnr  ?  HFP_HF_ECNR  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > cw  ?  HFP_HF_CW  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > cid  ?  HFP_HF_CID  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > voice  ?  HFP_HF_VOICE  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > volume  ?  HFP_HF_VOLUME  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > status  ?  HFP_HF_STATUS  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									brsf  | =  hf - > control  ?  HFP_HF_CONTROL  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  brsf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Convert  a  BRSF  int  to  an  hfp_ag  struct . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  brsf  a  brsf  integer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  ag  a  AG  ( hfp_ag )  brsf  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  a  pointer  to  the  given  hfp_ag  object  populated  with  the  values  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  given  brsf  integer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  hfp_ag  * hfp_int2brsf ( int  brsf ,  struct  hfp_ag  * ag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > cw  =  brsf  &  HFP_AG_CW  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > ecnr  =  brsf  &  HFP_AG_ECNR  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > voice  =  brsf  &  HFP_AG_VOICE  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > ring  =  brsf  &  HFP_AG_RING  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > tag  =  brsf  &  HFP_AG_TAG  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > reject  =  brsf  &  HFP_AG_REJECT  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > status  =  brsf  &  HFP_AG_STATUS  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > control  =  brsf  &  HFP_AG_CONTROL  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ag - > errors  =  brsf  &  HFP_AG_ERRORS  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  a  BRSF  request . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  brsf  an  hfp_hf  brsf  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_brsf ( struct  hfp_pvt  * hfp ,  struct  hfp_hf  * brsf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+BRSF=%d \r " ,  hfp_brsf2int ( brsf ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  the  CIND  read  command . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cind ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " AT+CIND? \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  the  CIND  test  command . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cind_test ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " AT+CIND=? \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Enable  or  disable  indicator  events  reporting . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  status  enable  or  disable  events  reporting  ( should  be  1  or  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmer ( struct  hfp_pvt  * hfp ,  int  status )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CMER=3,0,0,%d \r " ,  status  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  the  current  speaker  gain  level . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  value  the  value  to  send  ( must  be  between  0  and  15 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_vgs ( struct  hfp_pvt  * hfp ,  int  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+VGS=%d \r " ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#if 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  the  current  microphone  gain  level . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  value  the  value  to  send  ( must  be  between  0  and  15 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_vgm ( struct  hfp_pvt  * hfp ,  int  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+VGM=%d \r " ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Enable  or  disable  calling  line  identification . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  status  enable  or  disable  calling  line  identification  ( should  be  1  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_clip ( struct  hfp_pvt  * hfp ,  int  status )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CLIP=%d \r " ,  status  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  a  DTMF  command . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  digit  the  dtmf  digit  to  send 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  the  result  of  rfcomm_write ( )  or  - 1  on  an  invalid  digit  being  sent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_dtmf ( struct  hfp_pvt  * hfp ,  char  digit )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 10 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch ( digit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 0 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 1 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 2 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 3 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 4 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 5 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 6 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 7 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 8 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 9 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' * ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' # ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+VTS=%c \r " ,  digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Set  the  SMS  mode . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  mode  the  sms  mode  ( 0  =  PDU ,  1  =  Text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgf ( struct  hfp_pvt  * hfp ,  int  mode )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CMGF=%d \r " ,  mode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Setup  SMS  new  message  indication . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cnmi ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " AT+CNMI=2,1,0,0,0 \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  an  SMS  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  index  the  location  of  the  requested  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgr ( struct  hfp_pvt  * hfp ,  int  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CMGR=%d \r " ,  index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Start  sending  an  SMS  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  number  the  destination  of  the  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cmgs ( struct  hfp_pvt  * hfp ,  const  char  * number )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 64 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CMGS= \" %s \" \r " ,  number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  the  text  of  an  SMS  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  message  the  text  of  the  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_sms_text ( struct  hfp_pvt  * hfp ,  const  char  * message )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 162 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " %.160s \x1a " ,  message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  AT + CHUP . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_chup ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " AT+CHUP \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  ATD . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  number  the  number  to  send 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_atd ( struct  hfp_pvt  * hfp ,  const  char  * number )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 64 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " ATD%s; \r " ,  number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  ATA . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_ata ( struct  hfp_pvt  * hfp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  " ATA \r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  CUSD . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  code  the  CUSD  code  to  send 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_send_cusd ( struct  hfp_pvt  * hfp ,  const  char  * code )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 128 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " AT+CUSD=1, \" %s \" ,15 \r " ,  code ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( hfp - > rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  BRSF  data . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_brsf ( struct  hfp_pvt  * hfp ,  const  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  brsf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sscanf ( buf ,  " +BRSF:%d " ,  & brsf ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp_int2brsf ( brsf ,  & hfp - > brsf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  and  store  the  given  indicator . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  group  the  indicator  group 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  indicator  the  indicator  to  parse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cind_indicator ( struct  hfp_pvt  * hfp ,  int  group ,  char  * indicator )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* store the current indicator */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												Fix a variety of potential buffer overflows
* chan_mobile: Fixed an overrun where the cind_state buffer (an integer array
  of size 16) would be overrun due to improper bounds checking. At worst, the
  buffer can be overrun by a total of 48 bytes (assuming 4-byte integers),
  which would still leave it within the allocated memory of struct hfp.  This
  would corrupt other elements in that struct but not necessarily cause any
  further issues.
* app_sms: The array imsg is of size 250, while the array (ud) that the data
  is copied into is of size 160.  If the size of the inbound message is 
  greater then 160, up to 90 bytes could be overrun in ud.  This would corrupt
  the user data header (array udh) adjacent to ud.
* chan_unistim: A number of invalid memmoves are corrected.  These would move
  data (which may or may not be valid) into the ends of these buffers.
* asterisk: ast_console_toggle_loglevel does not check that the console log
  level being set is less then or equal to the allowed log levels of 32.
* format_pref: In ast_codec_pref_prepend, if any occurrence of the specified
  codec is not found, the value used to index into the array pref->order
  would be one greater then the maximum size of the array.
* jitterbuf: If the element being placed into the jitter buffer lands in the
  last available slot in the jitter history buffer, the insertion sort attempts
  to move the last entry in the buffer into one slot past the maximum length
  of the buffer.  Note that this occurred for both the min and max jitter
  history buffers.
* tdd: If a read from fsk_serial returns a character that is greater then 32,
  an attempt to read past one of the statically defined arrays containing the
  values that character maps to would occur.
* localtime: struct ast_time and tm are not the same size - ast_time is larger,
  although it contains the elements of tm within it in the same layout.  Hence,
  when using memcpy to copy the contents of tm into ast_time, the size of tm
  should be used, as opposed to the size of ast_time.
* extconf: this treats ast_timing's minmask array as if it had a length of 48,
  when it has defined the size of the array as 24.  pbx.h defines minmask as
  having a size of 48.
(issue ASTERISK-19668)
Reported by: Matt Jordan
........
Merged revisions 362485 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 362496 from http://svn.asterisk.org/svn/asterisk/branches/10
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@362497 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2012-04-19 02:40:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( group  > =  ARRAY_LEN ( hfp - > cind_state ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " ignoring CIND state '%s' for group %d, we only support up to %d indicators \n " ,  indicator ,  group ,  ( int )  sizeof ( hfp - > cind_state ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sscanf ( indicator ,  " %d " ,  & value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " error parsing CIND state '%s' for group %d \n " ,  indicator ,  group ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp - > cind_state [ group ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Read  the  result  of  the  AT + CIND ?  command . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  hfp_send_cind_test ( )  and  hfp_parse_cind_test ( )  should  be  called  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  least  once  before  this  function  is  called . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cind ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  state ,  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * indicator  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse current state of all of our indicators.  The list is in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  following  format : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  + CIND :  1 , 0 , 2 , 0 , 0 , 0 , 0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									group  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  strlen ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  s ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  0 :  /* search for start of the status indicators (a space) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  '   ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												group + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 :  /* mark this indicator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											indicator  =  & buf [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  2 :  /* search for the start of the next indicator (a comma) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' , ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf [ i ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hfp_parse_cind_indicator ( hfp ,  group ,  indicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												group + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* store the last indicator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( state  = =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hfp_parse_cind_indicator ( hfp ,  group ,  indicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Parse  the  result  of  the  AT + CIND = ?  command . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  hfp  an  hfp_pvt  struct 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  the  buffer  to  parse  ( null  terminated ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hfp_parse_cind_test ( struct  hfp_pvt  * hfp ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  state ,  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  s ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-14 15:51:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * indicator  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp - > nocallsetup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse the indications list.  It is in the follwing format:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  + CIND :  ( " ind1 " , ( 0 - 1 ) ) , ( " ind2 " , ( 0 - 5 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									group  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  =  strlen ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  s ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  0 :  /* search for start of indicator block */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' ( ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												group + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 :  /* search for '"' in indicator block */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  2 :  /* mark the start of the indicator name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											indicator  =  & buf [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  3 :  /* look for the end of the indicator name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' " ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf [ i ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  4 :  /* find the start of the value range */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' ( ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  5 :  /* mark the start of the value range */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  6 :  /* find the end of the value range */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( buf [ i ]  = =  ' ) ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf [ i ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  7 :  /* process the values we found */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( group  <  sizeof ( hfp - > cind_index ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! strcmp ( indicator ,  " service " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . service  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_SERVICE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " call " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . call  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_CALL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " callsetup " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > nocallsetup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . callsetup  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_CALLSETUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " call_setup " ) )  {  /* non standard call setup identifier */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > nocallsetup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . callsetup  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_CALLSETUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " callheld " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . callheld  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_CALLHELD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " signal " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . signal  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_SIGNAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " roam " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . roam  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_ROAM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! strcmp ( indicator ,  " battchg " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_map . battchg  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_BATTCHG ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hfp - > cind_index [ group ]  =  HFP_CIND_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 2 ,  " ignoring unknown CIND indicator '%s' \n " ,  indicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " can't store indicator %d (%s), we only support up to %d indicators " ,  group ,  indicator ,  ( int )  sizeof ( hfp - > cind_index ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp - > owner - > no_callsetup  =  hfp - > nocallsetup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Bluetooth  Headset  Profile  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  an  OK  AT  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_ok ( int  rsock )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( rsock ,  " \r \n OK \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  an  ERROR  AT  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_error ( int  rsock )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( rsock ,  " \r \n ERROR \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  a  speaker  gain  unsolicited  AT  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  gain  the  speaker  gain  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_vgs ( int  rsock ,  int  gain )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " \r \n +VGS=%d \r \n " ,  gain ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  a  microphone  gain  unsolicited  AT  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  gain  the  microphone  gain  value 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_vgm ( int  rsock ,  int  gain )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  cmd [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( cmd ,  sizeof ( cmd ) ,  " \r \n +VGM=%d \r \n " ,  gain ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( rsock ,  cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  a  RING  unsolicited  AT  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  rsock  the  rfcomm  socket  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  hsp_send_ring ( int  rsock )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rfcomm_write ( rsock ,  " \r \n RING \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  message  queue  functions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Add  an  item  to  the  back  of  the  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  expect  the  msg  we  expect  to  receive 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ param  response_to  the  message  that  was  sent  to  generate  the  expected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  msg_queue_push ( struct  mbl_pvt  * pvt ,  at_message_t  expect ,  at_message_t  response_to )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( msg  =  ast_calloc ( 1 ,  sizeof ( * msg ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg - > expected  =  expect ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg - > response_to  =  response_to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_INSERT_TAIL ( & pvt - > msg_queue ,  msg ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Add  an  item  to  the  back  of  the  queue  with  data . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  expect  the  msg  we  expect  to  receive 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ param  response_to  the  message  that  was  sent  to  generate  the  expected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  data  data  associated  with  this  message ,  it  will  be  freed  when  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  message  is  freed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  msg_queue_push_data ( struct  mbl_pvt  * pvt ,  at_message_t  expect ,  at_message_t  response_to ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( msg  =  ast_calloc ( 1 ,  sizeof ( * msg ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg - > expected  =  expect ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg - > response_to  =  response_to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg - > data  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_INSERT_TAIL ( & pvt - > msg_queue ,  msg ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Remove  an  item  from  the  front  of  the  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  a  pointer  to  the  removed  item 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  msg_queue_entry  * msg_queue_pop ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_LIST_REMOVE_HEAD ( & pvt - > msg_queue ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Remove  an  item  from  the  front  of  the  queue ,  and  free  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  msg_queue_free_and_pop ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( msg  =  msg_queue_pop ( pvt ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( msg - > data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_free ( msg - > data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Remove  all  items  from  the  queue  and  free  them . 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  msg_queue_flush ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( msg  =  msg_queue_head ( pvt ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Get  the  head  of  a  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  a  pointer  to  the  head  of  the  given  msg  queue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  msg_queue_entry  * msg_queue_head ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_LIST_FIRST ( & pvt - > msg_queue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp  helpers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  sdp_search ( char  * addr ,  int  profile )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_session_t  * session  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bdaddr_t  bdaddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uuid_t  svc_uuid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  range  =  0x0000ffff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_t  * response_list ,  * search_list ,  * attrid_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  status ,  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_t  * proto_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_record_t  * sdprec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str2ba ( addr ,  & bdaddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									port  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									session  =  sdp_connect ( BDADDR_ANY ,  & bdaddr ,  SDP_RETRY_IF_BUSY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! session )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " sdp_connect() failed on device %s. \n " ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid32_create ( & svc_uuid ,  profile ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									search_list  =  sdp_list_append ( 0 ,  & svc_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									attrid_list  =  sdp_list_append ( 0 ,  & range ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									response_list  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									status  =  sdp_service_search_attr_req ( session ,  search_list ,  SDP_ATTR_REQ_RANGE ,  attrid_list ,  & response_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( status  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( response_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sdprec  =  ( sdp_record_t  * )  response_list - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											proto_list  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( sdp_get_access_protos ( sdprec ,  & proto_list )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												port  =  sdp_get_proto_port ( proto_list ,  RFCOMM_UUID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sdp_list_free ( proto_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sdp_record_free ( sdprec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sdp_list_free ( response_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " No responses returned for device %s. \n " ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " sdp_service_search_attr_req() failed on device %s. \n " ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( search_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( attrid_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_close ( session ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  sdp_session_t  * sdp_register ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  service_uuid_int [ ]  =  { 0 ,  0 ,  0 ,  GENERIC_AUDIO_SVCLASS_ID } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint8_t  rfcomm_channel  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * service_name  =  " Asterisk PABX " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * service_dsc  =  " Asterisk PABX " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * service_prov  =  " Asterisk " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uuid_t  root_uuid ,  l2cap_uuid ,  rfcomm_uuid ,  svc_uuid ,  svc_class1_uuid ,  svc_class2_uuid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_t   * l2cap_list  =  0 ,  * rfcomm_list  =  0 ,  * root_list  =  0 ,  * proto_list  =  0 ,  * access_proto_list  =  0 ,  * svc_uuid_list  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_data_t  * channel  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_session_t  * session  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_record_t  * record  =  sdp_record_alloc ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid128_create ( & svc_uuid ,  & service_uuid_int ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_set_service_id ( record ,  svc_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid32_create ( & svc_class1_uuid ,  GENERIC_AUDIO_SVCLASS_ID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid32_create ( & svc_class2_uuid ,  HEADSET_PROFILE_ID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									svc_uuid_list  =  sdp_list_append ( 0 ,  & svc_class1_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									svc_uuid_list  =  sdp_list_append ( svc_uuid_list ,  & svc_class2_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_set_service_classes ( record ,  svc_uuid_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid16_create ( & root_uuid ,  PUBLIC_BROWSE_GROUP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									root_list  =  sdp_list_append ( 0 ,  & root_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_set_browse_groups (  record ,  root_list  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid16_create ( & l2cap_uuid ,  L2CAP_UUID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									l2cap_list  =  sdp_list_append ( 0 ,  & l2cap_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									proto_list  =  sdp_list_append ( 0 ,  l2cap_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_uuid16_create ( & rfcomm_uuid ,  RFCOMM_UUID ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									channel  =  sdp_data_alloc ( SDP_UINT8 ,  & rfcomm_channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rfcomm_list  =  sdp_list_append ( 0 ,  & rfcomm_uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_append ( rfcomm_list ,  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_append ( proto_list ,  rfcomm_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									access_proto_list  =  sdp_list_append ( 0 ,  proto_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_set_access_protos ( record ,  access_proto_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_set_info_attr ( record ,  service_name ,  service_prov ,  service_dsc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( session  =  sdp_connect ( BDADDR_ANY ,  BDADDR_LOCAL ,  SDP_RETRY_IF_BUSY ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Failed to connect sdp and create session. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 20:49:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sdp_record_register ( session ,  record ,  0 )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to sdp_record_register error: %d \n " ,  errno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_data_free ( channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( rfcomm_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( root_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( access_proto_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_list_free ( svc_uuid_list ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  session ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Thread  routines 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  the  BRSF  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_brsf ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( entry  =  msg_queue_head ( pvt ) )  & &  entry - > expected  = =  AT_BRSF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hfp_parse_brsf ( pvt - > hfp ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error parsing BRSF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( msg_queue_push ( pvt ,  AT_OK ,  AT_BRSF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error handling BRSF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'BRSF' when expecting %s, ignoring \n " ,  pvt - > id ,  at_msg2str ( entry - > expected ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'BRSF' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  the  CIND  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cind ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( entry  =  msg_queue_head ( pvt ) )  & &  entry - > expected  = =  AT_CIND )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( entry - > response_to )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND_TEST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_parse_cind_test ( pvt - > hfp ,  buf )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CIND_TEST ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error performing CIND test \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_parse_cind ( pvt - > hfp ,  buf )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CIND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error getting CIND state \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error getting CIND state \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'CIND' when expecting %s, ignoring \n " ,  pvt - > id ,  at_msg2str ( entry - > expected ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'CIND' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  OK  AT  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ok ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( entry  =  msg_queue_head ( pvt ) )  & &  entry - > expected  = =  AT_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( entry - > response_to )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* initialization stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  AT_BRSF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] BSRF sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If this is a blackberry do CMER now, otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  continue  with  CIND  as  normal .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > blackberry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_cmer ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CMER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error sending CMER \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_cind_test ( pvt - > hfp )  | |  msg_queue_push ( pvt ,  AT_CIND ,  AT_CIND_TEST ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error sending CIND test \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND_TEST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] CIND test sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 2 ,  " [%s] call: %d \n " ,  pvt - > id ,  pvt - > hfp - > cind_map . call ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 2 ,  " [%s] callsetup: %d \n " ,  pvt - > id ,  pvt - > hfp - > cind_map . callsetup ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:13:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 2 ,  " [%s] service: %d \n " ,  pvt - > id ,  pvt - > hfp - > cind_map . service ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_send_cind ( pvt - > hfp )  | |  msg_queue_push ( pvt ,  AT_CIND ,  AT_CIND ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error requesting CIND state \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] CIND sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* check if a call is active */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > hfp - > cind_state [ pvt - > hfp - > cind_map . call ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Bluetooth Device %s has a call in progress - delaying connection. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If this is NOT a blackberry proceed with CMER,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  otherwise  send  CLIP .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! pvt - > blackberry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_cmer ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CMER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error sending CMER \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_clip ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CLIP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error enabling calling line notification \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] CMER sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If this is a blackberry proceed with the CIND test,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  otherwise  send  CLIP .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > blackberry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_cind_test ( pvt - > hfp )  | |  msg_queue_push ( pvt ,  AT_CIND ,  AT_CIND_TEST ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error sending CIND test \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_clip ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CLIP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error enabling calling line notification \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CLIP : 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] calling line indication enabled \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( hfp_send_ecam ( pvt - > hfp )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_ECAM ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error enabling Sony Ericsson call monitoring extensions \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_ECAM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] Sony Ericsson call monitoring is active on device \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( hfp_send_vgs ( pvt - > hfp ,  15 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_VGS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error synchronizing gain settings \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > timeout  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > hfp - > initialized  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 3 ,  " Bluetooth Device %s initialized and ready. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] volume level synchronization successful \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* set the SMS operating mode to text mode */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( pvt - > has_sms )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hfp_send_cmgf ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CMGF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " [%s] error setting CMGF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] sms text mode enabled \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* turn on SMS new message indication */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_send_cnmi ( pvt - > hfp )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CNMI ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error setting CNMI \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CNMI : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] sms new message indication enabled \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > has_sms  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* end initialization stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_A : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] answer sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_D : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] dial sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > outgoing  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_queue_control ( pvt ,  AST_CONTROL_PROGRESS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CHUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] successful hangup \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] successfully sent sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > outgoing_sms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VTS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] digit sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  AT_CUSD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] CUSD code sent successfully \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  AT_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] received OK for unhandled request: %s \n " ,  pvt - > id ,  at_msg2str ( entry - > response_to ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received AT message 'OK' when expecting %s, ignoring \n " ,  pvt - > id ,  at_msg2str ( entry - > expected ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'OK' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  ERROR  AT  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_error ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( entry  =  msg_queue_head ( pvt ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& &  ( entry - > expected  = =  AT_OK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											| |  entry - > expected  = =  AT_ERROR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											| |  entry - > expected  = =  AT_CMS_ERROR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											| |  entry - > expected  = =  AT_CMGR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											| |  entry - > expected  = =  AT_SMS_PROMPT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( entry - > response_to )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* initialization stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  AT_BRSF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error reading BSRF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND_TEST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error during CIND test \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error requesting CIND state \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error during CMER request \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CLIP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error enabling calling line indication \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] volume level synchronization failed \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* this is not a fatal error, let's continue with initialization */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* set the SMS operating mode to text mode */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_send_cmgf ( pvt - > hfp ,  1 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_CMGF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error setting CMGF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGF : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pvt - > has_sms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error setting CMGF \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] no SMS support \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CNMI : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pvt - > has_sms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error setting CNMI \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] no SMS support \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_ECAM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] Mobile does not support Sony Ericsson extensions \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* this is not a fatal error, let's continue with the initialization */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_send_vgs ( pvt - > hfp ,  15 )  | |  msg_queue_push ( pvt ,  AT_OK ,  AT_VGS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error synchronizing gain settings \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > timeout  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > hfp - > initialized  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 3 ,  " Bluetooth Device %s initialized and ready. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* end initialization stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_A : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] answer failed \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_D : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] dial failed \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needchup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_queue_control ( pvt ,  AST_CONTROL_CONGESTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CHUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error sending hangup, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error reading sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > incoming_sms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error sending sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > outgoing_sms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VTS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error sending digit \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  AT_CUSD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 0 ,  " [%s] error sending CUSD command \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  AT_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] received ERROR for unhandled request: %s \n " ,  pvt - > id ,  at_msg2str ( entry - > response_to ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received AT message 'ERROR' when expecting %s, ignoring \n " ,  pvt - > id ,  at_msg2str ( entry - > expected ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] received unexpected AT message 'ERROR' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  AT + CIEV  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ciev ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( hfp_parse_ciev ( pvt - > hfp ,  buf ,  & i ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  HFP_CIND_CALL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALL_NONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] line disconnected \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] hanging up owner \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( mbl_queue_hangup ( pvt ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_ERROR ,  " [%s] error queueing hangup, disconnecting... \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needchup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needcallerid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > incoming  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > outgoing  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALL_ACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > outgoing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] remote end answered \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mbl_queue_control ( pvt ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( pvt - > incoming  & &  pvt - > answered )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_setstate ( pvt - > owner ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( pvt - > incoming )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* user answered from handset, disconnecting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " [%s] user answered bluetooth device from handset, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  HFP_CIND_CALLSETUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALLSETUP_NONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > hfp - > cind_state [ pvt - > hfp - > cind_map . call ]  ! =  HFP_CIND_CALL_ACTIVE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( pvt - > hfp - > sent_alerting  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														handle_response_busy ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( mbl_queue_hangup ( pvt ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_log ( LOG_ERROR ,  " [%s] error queueing hangup, disconnecting... \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > needchup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > needcallerid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > incoming  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > outgoing  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALLSETUP_INCOMING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] incoming call, waiting for caller id \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > needcallerid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > incoming  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALLSETUP_OUTGOING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > outgoing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pvt - > hfp - > sent_alerting  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] outgoing call \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " [%s] user dialed from handset, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  HFP_CIND_CALLSETUP_ALERTING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > outgoing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] remote alerting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mbl_queue_control ( pvt ,  AST_CONTROL_RINGING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												pvt - > hfp - > sent_alerting  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  HFP_CIND_NONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error parsing CIND: %s \n " ,  pvt - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  AT + CLIP  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_clip ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  cidinfo  cidinfo ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( msg  =  msg_queue_head ( pvt ) )  & &  msg - > expected  = =  AT_CLIP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > needcallerid  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cidinfo  =  hfp_parse_clip ( pvt - > hfp ,  buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( chan  =  mbl_new ( AST_STATE_RING ,  pvt ,  & cidinfo ,  NULL ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " [%s] unable to allocate channel for incoming call \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hfp_send_chup ( pvt - > hfp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											msg_queue_push ( pvt ,  AT_OK ,  AT_CHUP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* from this point on, we need to send a chup in the event of a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  hangup  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_pbx_start ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " [%s] unable to start pbx on incoming call \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_ast_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  RING  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_ring ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > needcallerid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] got ring while waiting for caller id \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  msg_queue_push ( pvt ,  AT_CLIP ,  AT_UNKNOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  AT + CMTI  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cmti ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  index  =  hfp_parse_cmti ( pvt - > hfp ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( index  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] incoming sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hfp_send_cmgr ( pvt - > hfp ,  index ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												| |  msg_queue_push ( pvt ,  AT_CMGR ,  AT_CMGR ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error sending CMGR to retrieve SMS message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > incoming_sms  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error parsing incoming sms message alert, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  AT + CMGR  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cmgr ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * from_number  =  NULL ,  * text  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( msg  =  msg_queue_head ( pvt ) )  & &  msg - > expected  = =  AT_CMGR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( hfp_parse_cmgr ( pvt - > hfp ,  buf ,  & from_number ,  & text ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error parsing sms message, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-02 21:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] successfully read sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > incoming_sms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* XXX this channel probably does not need to be associated with this pvt */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( chan  =  mbl_new ( AST_STATE_DOWN ,  pvt ,  NULL ,  NULL ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error creating sms message channel, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_exten_set ( chan ,  " sms " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " SMSSRC " ,  from_number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " SMSTXT " ,  text ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_pbx_start ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " [%s] unable to start pbx on incoming sms \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_ast_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] got unexpected +CMGR message, ignoring \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Send  an  SMS  message  from  the  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_sms_prompt ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( msg  =  msg_queue_head ( pvt ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error, got sms prompt with no pending sms messages \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( msg - > expected  ! =  AT_SMS_PROMPT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error, got sms prompt but no pending sms messages \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hfp_send_sms_text ( pvt - > hfp ,  msg - > data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											| |  msg_queue_push ( pvt ,  AT_OK ,  AT_CMGS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error sending sms message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_free_and_pop ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  CUSD  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_cusd ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cusd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( cusd  =  hfp_parse_cusd ( pvt - > hfp ,  buf ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verb ( 0 ,  " [%s] error parsing CUSD: %s \n " ,  pvt - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 0 ,  " [%s] CUSD response: %s \n " ,  pvt - > id ,  cusd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  BUSY  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_busy ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > hangupcause  =  AST_CAUSE_USER_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mbl_queue_control ( pvt ,  AST_CONTROL_BUSY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  NO  DIALTONE  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_no_dialtone ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 1 ,  " [%s] mobile reports NO DIALTONE \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mbl_queue_control ( pvt ,  AST_CONTROL_CONGESTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Handle  NO  CARRIER  messages . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  a  mbl_pvt  structure 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  buf  a  null  terminated  buffer  containing  an  AT  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  handle_response_no_carrier ( struct  mbl_pvt  * pvt ,  char  * buf )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 1 ,  " [%s] mobile reports NO CARRIER \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > needchup  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mbl_queue_control ( pvt ,  AST_CONTROL_CONGESTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_monitor_phone ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ( struct  mbl_pvt  * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hfp_pvt  * hfp  =  pvt - > hfp ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-09 00:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  buf [ 350 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									at_message_t  at_msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  msg_queue_entry  * entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Note: At one point the initialization procedure was neatly contained
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  in  the  hfp_init ( )  function ,  but  that  initialization  method  did  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  work  with  non  standard  devices .   As  a  result ,  the  initialization 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 *  procedure  is  not  spread  throughout  the  event  handling  loop . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* start initialization with the BRSF request */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > timeout  =  10000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hfp_send_brsf ( hfp ,  & hfp_our_brsf )   | |  msg_queue_push ( pvt ,  AT_BRSF ,  AT_BRSF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error sending BRSF \n " ,  hfp - > owner - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! check_unloading ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t  =  pvt - > timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! rfcomm_wait ( pvt - > rfcomm_socket ,  & t ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] timeout waiting for rfcomm data, disconnecting \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! hfp - > initialized )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( entry  =  msg_queue_head ( pvt ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													switch  ( entry - > response_to )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													case  AT_CIND_TEST : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( pvt - > blackberry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_debug ( 1 ,  " [%s] timeout during CIND test \n " ,  hfp - > owner - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_debug ( 1 ,  " [%s] timeout during CIND test, try setting 'blackberry=yes' \n " ,  hfp - > owner - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													case  AT_CMER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( pvt - > blackberry ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_debug ( 1 ,  " [%s] timeout after sending CMER, try setting 'blackberry=no' \n " ,  hfp - > owner - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_debug ( 1 ,  " [%s] timeout after sending CMER \n " ,  hfp - > owner - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " [%s] timeout while waiting for %s in response to %s \n " ,  pvt - > id ,  at_msg2str ( entry - > expected ) ,  at_msg2str ( entry - > response_to ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( at_msg  =  at_read_full ( hfp - > rsock ,  buf ,  sizeof ( buf ) ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error reading from device: %s (%d) \n " ,  pvt - > id ,  strerror ( errno ) ,  errno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-17 19:15:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] read %s \n " ,  pvt - > id ,  buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( at_msg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_BRSF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_brsf ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_cind ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_OK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_ok ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMS_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_error ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_ring ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CIEV : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_ciev ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CLIP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_clip ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMTI : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_cmti ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CMGR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_cmgr ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_SMS_PROMPT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_sms_prompt ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-29 21:46:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  AT_CUSD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_cusd ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-15 23:54:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  AT_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_busy ( pvt ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_NO_DIALTONE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_no_dialtone ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_NO_CARRIER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle_response_no_carrier ( pvt ,  buf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_ECAM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hfp_parse_ecav ( hfp ,  buf )  = =  7 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( handle_response_busy ( pvt ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  AT_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] ignoring unknown message: %s \n " ,  pvt - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_PARSE_ERROR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error parsing message \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_READ_ERROR : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error reading from device: %s (%d) \n " ,  pvt - > id ,  strerror ( errno ) ,  errno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_cleanup :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! hfp - > initialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Error initializing Bluetooth device %s. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] device disconnected, hanging up owner \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > needchup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( pvt - > rfcomm_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									msg_queue_flush ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > connected  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hfp - > initialized  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > adapter - > inuse  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " Bluetooth Device %s has disconnected. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_SYSTEM ,  " MobileStatus " ,  " Status: Disconnect \r \n Device: %s \r \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  headset_send_ring ( const  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ( struct  mbl_pvt  * )  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pvt - > needring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hsp_send_ring ( pvt - > rfcomm_socket ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] error sending RING \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_monitor_headset ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt  =  ( struct  mbl_pvt  * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  buf [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									at_message_t  at_msg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " Bluetooth Device %s initialised and ready. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! check_unloading ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t  =  ast_sched_wait ( pvt - > sched ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( t  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t  =  6000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_sched_runq ( pvt - > sched ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rfcomm_wait ( pvt - > rfcomm_socket ,  & t )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( at_msg  =  at_read_full ( pvt - > rfcomm_socket ,  buf ,  sizeof ( buf ) ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:29:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] error reading from device: %s (%d) \n " ,  pvt - > id ,  strerror ( errno ) ,  errno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] %s \n " ,  pvt - > id ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( at_msg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_VGM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* XXX volume change requested, we will just
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  pretend  to  do  something  with  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hsp_send_ok ( pvt - > rfcomm_socket ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error sending AT message 'OK' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AT_CKPD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > outgoing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > needring  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hsp_send_ok ( pvt - > rfcomm_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( pvt - > answered )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* we have an answered call up to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  HS ,  he  wants  to  hangup  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* we have an outgoing call to the HS,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  he  wants  to  answer  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ( pvt - > sco_socket  =  sco_connect ( pvt - > adapter - > addr ,  pvt - > addr ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_ERROR ,  " [%s] unable to create audio connection \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_set_fd ( pvt - > owner ,  0 ,  pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													mbl_queue_control ( pvt ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pvt - > answered  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( hsp_send_vgs ( pvt - > rfcomm_socket ,  13 )  | |  hsp_send_vgm ( pvt - > rfcomm_socket ,  13 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " [%s] error sending VGS/VGM \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( pvt - > incoming )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* we have an incoming call from the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  HS ,  he  wants  to  hang  up  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* no call is up, HS wants to dial */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hsp_send_ok ( pvt - > rfcomm_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ( pvt - > sco_socket  =  sco_connect ( pvt - > adapter - > addr ,  pvt - > addr ) )  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_ERROR ,  " [%s] unable to create audio connection \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > incoming  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												uniqueid: channel linkedid, ami, ari object creation with id's
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.
Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.
(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........
Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-03-07 15:47:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! ( chan  =  mbl_new ( AST_STATE_UP ,  pvt ,  NULL ,  NULL ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_ERROR ,  " [%s] unable to allocate channel for incoming call \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_set_fd ( chan ,  0 ,  pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_exten_set ( chan ,  " s " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( ast_pbx_start ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_ERROR ,  " [%s] unable to start pbx on incoming call \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " [%s] received unknown AT command: %s (%s) \n " ,  pvt - > id ,  buf ,  at_msg2str ( at_msg ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hsp_send_error ( pvt - > rfcomm_socket ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " [%s] error sending AT message 'ERROR' \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_cleanup :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " [%s] device disconnected, hanging up owner \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mbl_queue_hangup ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( pvt - > rfcomm_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > connected  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > needring  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > outgoing  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > incoming  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > adapter - > inuse  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_SYSTEM ,  " MobileStatus " ,  " Status: Disconnect \r \n Device: %s \r \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " Bluetooth Device %s has disconnected \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  start_monitor ( struct  mbl_pvt  * pvt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_PHONE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > hfp - > rsock  =  pvt - > rfcomm_socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_pthread_create_background ( & pvt - > monitor_thread ,  NULL ,  do_monitor_phone ,  pvt )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > monitor_thread  =  AST_PTHREADT_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_pthread_create_background ( & pvt - > monitor_thread ,  NULL ,  do_monitor_headset ,  pvt )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > monitor_thread  =  AST_PTHREADT_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_discovery ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! check_unloading ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_RDLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_TRAVERSE ( & adapters ,  adapter ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! adapter - > inuse )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AST_RWLIST_RDLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AST_RWLIST_TRAVERSE ( & devices ,  pvt ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_lock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ! adapter - > inuse  & &  ! pvt - > connected  & &  ! strcmp ( adapter - > id ,  pvt - > adapter - > id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( ( pvt - > rfcomm_socket  =  rfcomm_connect ( adapter - > addr ,  pvt - > addr ,  pvt - > rfcomm_port ) )  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															if  ( start_monitor ( pvt ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																pvt - > connected  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																adapter - > inuse  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																manager_event ( EVENT_FLAG_SYSTEM ,  " MobileStatus " ,  " Status: Connect \r \n Device: %s \r \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 16:33:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																ast_verb ( 3 ,  " Bluetooth Device %s has connected, initializing... \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_mutex_unlock ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Go to sleep (only if we are not unloading) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! check_unloading ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sleep ( discovery_interval ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Service  new  and  existing  SCO  connections . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  thread  accepts  new  sco  connections  and  handles  audio  data .   There  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  one  do_sco_listen  thread  for  each  adapter . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_sco_listen ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter  =  ( struct  adapter_pvt  * )  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ! check_unloading ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* check for new sco connections */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 20:49:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_io_wait ( adapter - > accept_io ,  0 )  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* handle errors */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " ast_io_wait() failed for adapter %s \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* handle audio data */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 20:49:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_io_wait ( adapter - > io ,  1 )  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " ast_io_wait() failed for audio on adapter %s \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Module 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Load  an  adapter  from  the  configuration  file . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cfg  the  config  to  load  the  adapter  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cat  the  adapter  to  load 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  function  loads  the  given  adapter  and  starts  the  sco  listener  thread  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  that  adapter . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  NULL  on  error ,  a  pointer  to  the  adapter  that  was  loaded  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  adapter_pvt  * mbl_load_adapter ( struct  ast_config  * cfg ,  const  char  * cat )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * id ,  * address ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hci_dev_req  dr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint16_t  vs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  =  ast_variable_retrieve ( cfg ,  cat ,  " id " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									address  =  ast_variable_retrieve ( cfg ,  cat ,  " address " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( id )  | |  ast_strlen_zero ( address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter. Missing id or address settings. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Reading configuration for adapter %s %s. \n " ,  id ,  address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( adapter  =  ast_calloc ( 1 ,  sizeof ( * adapter ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Error allocating memory. \n " ,  id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( adapter - > id ,  id ,  sizeof ( adapter - > id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str2ba ( address ,  & adapter - > addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* attempt to connect to the adapter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									adapter - > dev_id  =  hci_devid ( address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									adapter - > hci_socket  =  hci_open_dev ( adapter - > dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( adapter - > dev_id  <  0  | |  adapter - > hci_socket  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Unable to communicate with adapter. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_free_adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* check voice setting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hci_read_voice_setting ( adapter - > hci_socket ,  & vs ,  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vs  =  htobs ( vs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( vs  ! =  0x0060 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Voice setting must be 0x0060 - see 'man hciconfig' for details. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_hci_close_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( v  =  ast_variable_browse ( cfg ,  cat ) ;  v ;  v  =  v - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( v - > name ,  " forcemaster " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_true ( v - > value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dr . dev_id  =  adapter - > dev_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hci_strtolm ( " master " ,  & dr . dev_opt ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ioctl ( adapter - > hci_socket ,  HCISETLINKMODE ,  ( unsigned  long )  & dr )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to set adapter %s link mode to MASTER. Ignoring 'forcemaster' option. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " alignmentdetection " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											adapter - > alignment_detection  =  ast_true ( v - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* create io contexts */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( adapter - > accept_io  =  io_context_create ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to create I/O context for audio connection listener \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_hci_close_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( adapter - > io  =  io_context_create ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to create I/O context for audio connections \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_destroy_accept_io ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* bind the sco listener socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sco_bind ( adapter )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Error binding audio connection listener socket. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  e_destroy_io ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* add the socket to the io context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( adapter - > sco_id  =  ast_io_add ( adapter - > accept_io ,  adapter - > sco_socket ,  sco_accept ,  AST_IO_IN ,  adapter ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Error adding listener socket to I/O context. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_close_sco ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* start the sco listener for this adapter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_pthread_create_background ( & adapter - > sco_listener_thread ,  NULL ,  do_sco_listen ,  adapter ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping adapter %s. Error creating audio connection listener thread. \n " ,  adapter - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  e_remove_sco ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* add the adapter to our global list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_INSERT_HEAD ( & adapters ,  adapter ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Loaded adapter %s %s. \n " ,  adapter - > id ,  address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_remove_sco :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_io_remove ( adapter - > accept_io ,  adapter - > sco_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_close_sco :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( adapter - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_destroy_io :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									io_context_destroy ( adapter - > io ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_destroy_accept_io :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									io_context_destroy ( adapter - > accept_io ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_hci_close_dev :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hci_close_dev ( adapter - > hci_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_free_adapter :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( adapter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Load  a  device  from  the  configuration  file . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cfg  the  config  to  load  the  device  from 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cat  the  device  to  load 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  NULL  on  error ,  a  pointer  to  the  device  that  was  loaded  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  mbl_pvt  * mbl_load_device ( struct  ast_config  * cfg ,  const  char  * cat )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * address ,  * adapter_str ,  * port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Reading configuration for device %s. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									adapter_str  =  ast_variable_retrieve ( cfg ,  cat ,  " adapter " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if ( ast_strlen_zero ( adapter_str ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. No adapter specified. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* find the adapter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_RDLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & adapters ,  adapter ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( adapter - > id ,  adapter_str ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! adapter )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:34 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Unknown adapter '%s' specified. \n " ,  cat ,  adapter_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									address  =  ast_variable_retrieve ( cfg ,  cat ,  " address " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									port  =  ast_variable_retrieve ( cfg ,  cat ,  " port " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( port )  | |  ast_strlen_zero ( address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Missing required port or address setting. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* create and initialize our pvt structure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( pvt  =  ast_calloc ( 1 ,  sizeof ( * pvt ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Error allocating memory. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_init ( & pvt - > lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( & pvt - > msg_queue ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* set some defaults */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > type  =  MBL_TYPE_PHONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( pvt - > context ,  " default " ,  sizeof ( pvt - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* populate the pvt structure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > adapter  =  adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( pvt - > id ,  cat ,  sizeof ( pvt - > id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str2ba ( address ,  & pvt - > addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > timeout  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > rfcomm_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > rfcomm_port  =  atoi ( port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > sco_socket  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > monitor_thread  =  AST_PTHREADT_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pvt - > ring_sched_id  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pvt - > has_sms  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* setup the bt_out_smoother */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( pvt - > bt_out_smoother  =  ast_smoother_new ( DEVICE_FRAME_SIZE ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Error setting up frame bt_out_smoother. \n " ,  cat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										goto  e_free_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* setup the bt_in_smoother */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( pvt - > bt_in_smoother  =  ast_smoother_new ( CHANNEL_FRAME_SIZE ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Error setting up frame bt_in_smoother. \n " ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_free_bt_out_smoother ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* setup the dsp */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( pvt - > dsp  =  ast_dsp_new ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Skipping device %s. Error setting up dsp for dtmf detection. \n " ,  cat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  e_free_bt_in_smoother ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* setup the scheduler */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-20 17:49:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( pvt - > sched  =  ast_sched_context_create ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to create scheduler context for headset device \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_free_dsp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_dsp_set_features ( pvt - > dsp ,  DSP_FEATURE_DIGIT_DETECT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_dsp_set_digitmode ( pvt - > dsp ,  DSP_DIGITMODE_DTMF  |  DSP_DIGITMODE_RELAXDTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( v  =  ast_variable_browse ( cfg ,  cat ) ;  v ;  v  =  v - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( v - > name ,  " type " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( v - > value ,  " headset " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > type  =  MBL_TYPE_HEADSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pvt - > type  =  MBL_TYPE_PHONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " context " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( pvt - > context ,  v - > value ,  sizeof ( pvt - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " group " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* group is set to 0 if invalid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > group  =  atoi ( v - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " sms " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > has_sms  =  ast_true ( v - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " nocallsetup " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > no_callsetup  =  ast_true ( v - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pvt - > no_callsetup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Setting nocallsetup mode for device %s. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( v - > name ,  " blackberry " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pvt - > blackberry  =  ast_true ( v - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pvt - > has_sms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pvt - > type  = =  MBL_TYPE_PHONE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( pvt - > hfp  =  ast_calloc ( 1 ,  sizeof ( * pvt - > hfp ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Skipping device %s. Error allocating memory. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  e_free_sched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > hfp - > owner  =  pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > hfp - > rport  =  pvt - > rfcomm_port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > hfp - > nocallsetup  =  pvt - > no_callsetup ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:01:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pvt - > has_sms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_INSERT_HEAD ( & devices ,  pvt ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Loaded device %s. \n " ,  pvt - > id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_free_sched :  
						 
					
						
							
								
									
										
										
										
											2010-12-20 17:49:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_sched_context_destroy ( pvt - > sched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								e_free_dsp :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_dsp_free ( pvt - > dsp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								e_free_bt_in_smoother :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_smoother_free ( pvt - > bt_in_smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_free_bt_out_smoother :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_smoother_free ( pvt - > bt_out_smoother ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								e_free_pvt :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_return :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mbl_load_config ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * cat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  config_flags  =  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  =  ast_config_load ( MBL_CONFIG ,  config_flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 17:16:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! cfg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cfg  =  ast_config_load ( MBL_CONFIG_OLD ,  config_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ! cfg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* parse [general] section */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( v  =  ast_variable_browse ( cfg ,  " general " ) ;  v ;  v  =  v - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( v - > name ,  " interval " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! sscanf ( v - > value ,  " %d " ,  & discovery_interval ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_NOTICE ,  " error parsing 'interval' in general section, using default value \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* load adapters */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( cat  =  ast_category_browse ( cfg ,  NULL ) ;  cat ;  cat  =  ast_category_browse ( cfg ,  cat ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( cat ,  " adapter " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_load_adapter ( cfg ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( AST_RWLIST_EMPTY ( & adapters ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" *********************************************************************** \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" No adapters could be loaded from the configuration file. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Please review mobile.conf. See sample for details. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" *********************************************************************** \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* now load devices */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( cat  =  ast_category_browse ( cfg ,  NULL ) ;  cat ;  cat  =  ast_category_browse ( cfg ,  cat ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcasecmp ( cat ,  " general " )  & &  strcasecmp ( cat ,  " adapter " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mbl_load_device ( cfg ,  cat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Check  if  the  module  is  unloading . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  not  unloading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  1  unloading 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  check_unloading ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & unload_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  unloading_flag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & unload_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Set  the  unloading  flag . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  void  set_unloading ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_lock ( & unload_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unloading_flag  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_mutex_unlock ( & unload_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  unload_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  mbl_pvt  * pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  adapter_pvt  * adapter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* First, take us out of the channel loop */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unregister ( & mbl_tech ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Unregister the CLI & APP */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli_unregister_multiple ( mbl_cli ,  sizeof ( mbl_cli )  /  sizeof ( mbl_cli [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_application ( app_mblstatus ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_application ( app_mblsendsms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* signal everyone we are unloading */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_unloading ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Kill the discovery thread */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( discovery_thread  ! =  AST_PTHREADT_NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_kill ( discovery_thread ,  SIGURG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_join ( discovery_thread ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* stop the sco listener threads */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & adapters ,  adapter ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_kill ( adapter - > sco_listener_thread ,  SIGURG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_join ( adapter - > sco_listener_thread ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Destroy the device list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( pvt  =  AST_RWLIST_REMOVE_HEAD ( & devices ,  entry ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > monitor_thread  ! =  AST_PTHREADT_NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pthread_kill ( pvt - > monitor_thread ,  SIGURG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pthread_join ( pvt - > monitor_thread ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( pvt - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( pvt - > rfcomm_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										msg_queue_flush ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pvt - > hfp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_free ( pvt - > hfp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-17 08:39:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_smoother_free ( pvt - > bt_out_smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_smoother_free ( pvt - > bt_in_smoother ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_dsp_free ( pvt - > dsp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-20 17:49:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_sched_context_destroy ( pvt - > sched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_free ( pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & devices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Destroy the adapter list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( adapter  =  AST_RWLIST_REMOVE_HEAD ( & adapters ,  entry ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( adapter - > sco_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										io_context_destroy ( adapter - > io ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										io_context_destroy ( adapter - > accept_io ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hci_close_dev ( adapter - > hci_socket ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( adapter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & adapters ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sdp_session ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sdp_close ( sdp_session ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ao2_ref ( mbl_tech . capabilities ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mbl_tech . capabilities  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  dev_id ,  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( mbl_tech . capabilities  =  ast_format_cap_alloc ( AST_FORMAT_CAP_FLAG_DEFAULT ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 16:22:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
 1. Asterisk was limited in how many formats it could handle.
 2. Formats, being a bit field, could not include any attribute information.
    A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
 * The ast_format structure is reference counted. This removed a large amount
   of the memory allocations and copying that was done in prior versions.
 * In order to prevent race conditions while keeping things performant, the
   ast_format structure is immutable by convention and lock-free. Violate this
   tenet at your peril!
 * Because formats are reference counted, codecs are also reference counted.
   The Asterisk core generally provides built-in codecs and caches the
   ast_format structures created to represent them. Generally, to prevent
   inordinate amounts of module reference bumping, codecs and formats can be
   added at run-time but cannot be removed.
 * All compatibility with the bit field representation of codecs/formats has
   been moved to a compatibility API. The primary user of this representation
   is chan_iax2, which must continue to maintain its bit-field usage of formats
   for interoperability concerns.
 * When a format is negotiated with attributes, or when a format cannot be
   represented by one of the cached formats, a new format object is created or
   cloned from an existing format. That format may have the same codec
   underlying it, but is a different format than a version of the format with
   different attributes or without attributes.
 * While formats are reference counted objects, the reference count maintained
   on the format should be manipulated with care. Formats are generally cached
   and will persist for the lifetime of Asterisk and do not explicitly need
   to have their lifetime modified. An exception to this is when the user of a
   format does not know where the format came from *and* the user may outlive
   the provider of the format. This occurs, for example, when a format is read
   from a channel: the channel may have a format with attributes (hence,
   non-cached) and the user of the format may last longer than the channel (if
   the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
  https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
 https://reviewboard.asterisk.org/r/3814
 https://reviewboard.asterisk.org/r/3808
 https://reviewboard.asterisk.org/r/3805
 https://reviewboard.asterisk.org/r/3803
 https://reviewboard.asterisk.org/r/3801
 https://reviewboard.asterisk.org/r/3798
 https://reviewboard.asterisk.org/r/3800
 https://reviewboard.asterisk.org/r/3794
 https://reviewboard.asterisk.org/r/3793
 https://reviewboard.asterisk.org/r/3792
 https://reviewboard.asterisk.org/r/3791
 https://reviewboard.asterisk.org/r/3790
 https://reviewboard.asterisk.org/r/3789
 https://reviewboard.asterisk.org/r/3788
 https://reviewboard.asterisk.org/r/3787
 https://reviewboard.asterisk.org/r/3786
 https://reviewboard.asterisk.org/r/3784
 https://reviewboard.asterisk.org/r/3783
 https://reviewboard.asterisk.org/r/3778
 https://reviewboard.asterisk.org/r/3774
 https://reviewboard.asterisk.org/r/3775
 https://reviewboard.asterisk.org/r/3772
 https://reviewboard.asterisk.org/r/3761
 https://reviewboard.asterisk.org/r/3754
 https://reviewboard.asterisk.org/r/3753
 https://reviewboard.asterisk.org/r/3751
 https://reviewboard.asterisk.org/r/3750
 https://reviewboard.asterisk.org/r/3748
 https://reviewboard.asterisk.org/r/3747
 https://reviewboard.asterisk.org/r/3746
 https://reviewboard.asterisk.org/r/3742
 https://reviewboard.asterisk.org/r/3740
 https://reviewboard.asterisk.org/r/3739
 https://reviewboard.asterisk.org/r/3738
 https://reviewboard.asterisk.org/r/3737
 https://reviewboard.asterisk.org/r/3736
 https://reviewboard.asterisk.org/r/3734
 https://reviewboard.asterisk.org/r/3722
 https://reviewboard.asterisk.org/r/3713
 https://reviewboard.asterisk.org/r/3703
 https://reviewboard.asterisk.org/r/3689
 https://reviewboard.asterisk.org/r/3687
 https://reviewboard.asterisk.org/r/3674
 https://reviewboard.asterisk.org/r/3671
 https://reviewboard.asterisk.org/r/3667
 https://reviewboard.asterisk.org/r/3665
 https://reviewboard.asterisk.org/r/3625
 https://reviewboard.asterisk.org/r/3602
 https://reviewboard.asterisk.org/r/3519
 https://reviewboard.asterisk.org/r/3518
 https://reviewboard.asterisk.org/r/3516
 https://reviewboard.asterisk.org/r/3515
 https://reviewboard.asterisk.org/r/3512
 https://reviewboard.asterisk.org/r/3506
 https://reviewboard.asterisk.org/r/3413
 https://reviewboard.asterisk.org/r/3410
 https://reviewboard.asterisk.org/r/3387
 https://reviewboard.asterisk.org/r/3388
 https://reviewboard.asterisk.org/r/3389
 https://reviewboard.asterisk.org/r/3390
 https://reviewboard.asterisk.org/r/3321
 https://reviewboard.asterisk.org/r/3320
 https://reviewboard.asterisk.org/r/3319
 https://reviewboard.asterisk.org/r/3318
 https://reviewboard.asterisk.org/r/3266
 https://reviewboard.asterisk.org/r/3265
 https://reviewboard.asterisk.org/r/3234
 https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
  media_formats_translation_core.diff uploaded by kharwell (License 6464)
  rb3506.diff uploaded by mjordan (License 6283)
  media_format_app_file.diff uploaded by kharwell (License 6464) 
  misc-2.diff uploaded by file (License 5000)
  chan_mild-3.diff uploaded by file (License 5000) 
  chan_obscure.diff uploaded by file (License 5000) 
  jingle.diff uploaded by file (License 5000) 
  funcs.diff uploaded by file (License 5000) 
  formats.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  bridges.diff uploaded by file (License 5000) 
  mf-codecs-2.diff uploaded by file (License 5000) 
  mf-app_fax.diff uploaded by file (License 5000) 
  mf-apps-3.diff uploaded by file (License 5000) 
  media-formats-3.diff uploaded by file (License 5000) 
ASTERISK-23715
  rb3713.patch uploaded by coreyfarrell (License 5909)
  rb3689.patch uploaded by mjordan (License 6283)
  
ASTERISK-23957
  rb3722.patch uploaded by mjordan (License 6283) 
  mf-attributes-3.diff uploaded by file (License 5000) 
ASTERISK-23958
Tested by: jrose
  rb3822.patch uploaded by coreyfarrell (License 5909) 
  rb3800.patch uploaded by jrose (License 6182)
  chan_sip.diff uploaded by mjordan (License 6283) 
  rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
  sip_cleanup.diff uploaded by opticron (License 6273)
  chan_sip_caps.diff uploaded by mjordan (License 6283) 
  rb3751.patch uploaded by coreyfarrell (License 5909) 
  chan_sip-3.diff uploaded by file (License 5000) 
ASTERISK-23960 #close
Tested by: opticron
  direct_media.diff uploaded by opticron (License 6273) 
  pjsip-direct-media.diff uploaded by file (License 5000) 
  format_cap_remove.diff uploaded by opticron (License 6273) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  chan_pjsip-2.diff uploaded by file (License 5000) 
ASTERISK-23966 #close
Tested by: rmudgett
  rb3803.patch uploaded by rmudgetti (License 5621)
  chan_dahdi.diff uploaded by file (License 5000) 
  
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
  rb3814.patch uploaded by rmudgett (License 5621) 
  moh_cleanup.diff uploaded by opticron (License 6273) 
  bridge_leak.diff uploaded by opticron (License 6273) 
  translate.diff uploaded by file (License 5000) 
  rb3795.patch uploaded by rmudgett (License 5621) 
  tls_fix.diff uploaded by mjordan (License 6283) 
  fax-mf-fix-2.diff uploaded by file (License 5000) 
  rtp_transfer_stuff uploaded by mjordan (License 6283) 
  rb3787.patch uploaded by rmudgett (License 5621) 
  media-formats-explicit-translate-format-3.diff uploaded by file (License 5000) 
  format_cache_case_fix.diff uploaded by opticron (License 6273) 
  rb3774.patch uploaded by rmudgett (License 5621) 
  rb3775.patch uploaded by rmudgett (License 5621) 
  rtp_engine_fix.diff uploaded by opticron (License 6273) 
  rtp_crash_fix.diff uploaded by opticron (License 6273) 
  rb3753.patch uploaded by mjordan (License 6283) 
  rb3750.patch uploaded by mjordan (License 6283) 
  rb3748.patch uploaded by rmudgett (License 5621) 
  media_format_fixes.diff uploaded by opticron (License 6273) 
  rb3740.patch uploaded by mjordan (License 6283) 
  rb3739.patch uploaded by mjordan (License 6283) 
  rb3734.patch uploaded by mjordan (License 6283) 
  rb3689.patch uploaded by mjordan (License 6283) 
  rb3674.patch uploaded by coreyfarrell (License 5909) 
  rb3671.patch uploaded by coreyfarrell (License 5909) 
  rb3667.patch uploaded by coreyfarrell (License 5909) 
  rb3665.patch uploaded by mjordan (License 6283) 
  rb3625.patch uploaded by coreyfarrell (License 5909) 
  rb3602.patch uploaded by coreyfarrell (License 5909) 
  format_compatibility-2.diff uploaded by file (License 5000) 
  core.diff uploaded by file (License 5000) 
  
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-07-20 22:06:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_format_cap_append ( mbl_tech . capabilities ,  DEVICE_FRAME_FORMAT ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* Check if we have Bluetooth, no point loading otherwise... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev_id  =  hci_get_route ( NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									s  =  hci_open_dev ( dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev_id  <  0  | |  s  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " No Bluetooth devices found. Not loading module. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ao2_ref ( mbl_tech . capabilities ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mbl_tech . capabilities  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hci_close_dev ( s ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hci_close_dev ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( mbl_load_config ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Errors reading config file %s. Not loading module. \n " ,  MBL_CONFIG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ao2_ref ( mbl_tech . capabilities ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mbl_tech . capabilities  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sdp_session  =  sdp_register ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Spin the discovery thread */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_pthread_create_background ( & discovery_thread ,  NULL ,  do_discovery ,  NULL )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to create discovery thread. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* register our channel type */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_channel_register ( & mbl_tech ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to register channel class %s \n " ,  " Mobile " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  e_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli_register_multiple ( mbl_cli ,  sizeof ( mbl_cli )  /  sizeof ( mbl_cli [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_register_application ( app_mblstatus ,  mbl_status_exec ,  mblstatus_synopsis ,  mblstatus_desc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_register_application ( app_mblsendsms ,  mbl_sendsms_exec ,  mblsendsms_synopsis ,  mblsendsms_desc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_MODULE_LOAD_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e_cleanup :  
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unload_module ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 10:07:39 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-20 19:35:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								AST_MODULE_INFO ( ASTERISK_GPL_KEY ,  AST_MODFLAG_LOAD_ORDER ,  " Bluetooth Mobile Device Channel Driver " ,  
						 
					
						
							
								
									
										
										
										
											2015-05-05 20:49:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. support_level  =  AST_MODULE_SUPPORT_EXTENDED , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load  =  load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_pri  =  AST_MODPRI_CHANNEL_DRIVER , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-30 16:40:38 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								) ;